Búsqueda de sitios web

typescript - ¿Cómo obtener una propiedad predefinida de un subobjeto?


Esto funciona como se espera

const a = {
  b: {
    c: 2
  }
}
const propOf = <T, K extends keyof T, P extends keyof T[K]>(
    obj: T,
    key: K,
    p: P
) => obj[key][p]

const d = propOf(a, 'b', 'c')

Permite extraer la propiedad c, pero estoy buscando una manera de definir una función que siempre extraiga c

const propC = <T, K extends keyof T>(obj: T, key: K) => obj[key].c
const e = propC(a, 'b')

Esto, sin embargo, me da un error

La propiedad 'c' no existe en el tipo 'T[K]'

¿Cómo debería escribir la función propC para que funcione correctamente?

Respuesta #1

Si sabes que el tipo b contiene la propiedad c, ¿por qué no usar un tipo predefinido? Por ejemplo:

type A = {
  [key: string]: {
    c: number
  }
}

const a: A = {
  b: {
    c: 2
  }
};

// access c prop directly
const c1 = a['b'].c;

// or the generic version
const propC = <T extends A>( obj: T, key: keyof T ) => obj[key].c
const c2 = propC(a, 'b')

No puedes acceder a la propiedad c dentro de la función genérica, porque la función no sabe nada sobre el tipo T. El tipo del objeto a es desconocido hasta que lo pases a la función y no está disponible para la función.

Respuesta #2

Caso más general, donde no conoces el tipo exacto de c, pero quieres inferirlo, sería así:

const a = {
    b: {
        c: 2
    }
};
const b = {
    b: {
        c: "text"
    }
};

type TypeOfPropC<T> = T extends { [key: string]: { c: infer U } } ? U : unknown;
const propC = <T extends { [key: string]: { c: TypeOfPropC<T> } }, K extends keyof T>(obj: T, key: K) => obj[key].c;

const e = propC(a, 'b'); // e is `number`
const f = propC(b, 'b'); // f is `string`