Por ejemplo, tengo estos datos en JS
const obj = { // never have 'c' property a: 1, b: 2, } const keys = ['a', 'b', 'c'] // always 'a'|'b'|'c' --> ex: [a,b,c] / [c,b,a] / [a,c] const firstKey = keys[0] const selectedObj = obj?.[firstKey] || 99Ahora, ¿cómo hacerlo en mecanografiado? Lo probé pero me quedé con esa solución.
type Keys = 'a' | 'b' | 'c' type ObjKey = Exclude<Keys, 'c'> type Obj = Record<ObjKey, number> const obj: Obj = { a: 1, b: 2, } const keys: Keys[] = ['a', 'b', 'c'] const firstKey = keys[0] as ObjKey // --> I don't think this is right const selectedObj = obj?.[firstKey] || 99 No creo que esto sea correcto, porque al hacerlo, elimino la posibilidad de que la verificación de tiempo de ejecución en firstKey tenga el valor 'c' . Me pregunto cuál es la forma correcta/adecuada de solucionar este problema. Quiero poder acceder al selectedObj , pero TS grita que
Property 'c' does not exist on type 'Obj'Todo lo que necesita hacer es cambiar la siguiente línea:
type Obj = Record<ObjKey, number>a
type Obj = Partial<Record<Keys, number>>Explicación:
En su pregunta, expresó el deseo de que TypeScript generara una advertencia/error de que la propiedad obj?.[firstKey] a la que se accedió puede no estar definida, lo que obligaría al desarrollador a agregar una verificación de tiempo de ejecución. En el ejemplo proporcionado, podemos ver que todas las propiedades de obj están definidas y TypeScript se quejará inmediatamente de su uso durante el tiempo de ejecución. La forma de moverse es hacer que todas las propiedades obj sean opcionales usando el tipo de utilidadParcial . Esto le indicará a TypeScript que la propiedad a la que se accede puede o no estar definida, por lo tanto, el desarrollador deberá agregar código para usarla.
Aquí hay un enlace de ts playground.
En su caso, donde mencionó que las claves de objeto no se cambiarán, le sugiero que reemplace esto:
type Keys = 'a' | 'b' | 'c' type ObjKey = Exclude<Keys, 'c'>con:
const keys = ['a', 'b', 'c'] as const; type ObjKey = Exclude<typeof keys[number], 'c'>Al hacer esto, está creando una construcción mecanografiada llamada aserción const que le permite tener un objeto inmutable.
Más documentos aquí: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions
Luego, normalmente puede usar una anotación de tipo en la variable firstKey sin recibir ningún error.
const firstKey: ObjKey = keys[0];