javascript - TypeScript: ¿El tipo devuelto al acceder a una clave indefinida en un objeto es incorrecto?
Noté tipos inesperados al usar objetos con claves variables en TypeScript.
Dado el siguiente código
type MyType = {
[x: number] : number
}
const o : MyType = {
0: 1,
}
const a = o[0]; // Return type correctly identified as number
const b = o[1]; // Return type should be undefined and compiler should not allow this
Noté que el tipo de un acceso a un objeto usando [...] no se detecta correctamente cuando el tipo de objeto se define usando la sintaxis [x: number] para claves variables.
VSCode me muestra que tanto a como b tienen tipo number. ¿No debería el tipo ser number | undefined en su lugar porque puede ocurrir que una clave sea undefined? Al registrar a y b en la consola, a es un number mientras que b es undefined.
El problema se vuelve más serio cuando un objeto de tipo MyType se pasa a una función y esta función accede a una clave en este objeto y luego hace algo como esto:
function fun(o: MyType) : number {
return o[10000] ?? null // can be number or null at runtime
}
No se muestra ningún error. Pero cuando se ejecuta el código, o[10000] es indefinido y, por lo tanto, el valor de retorno es null, lo cual no es un número válido. Imagínate usar este valor de retorno para realizar más cálculos que se basan en la suposición de que es un número válido. Esto conduciría a errores en tiempo de ejecución que deberían haber sido detectados por el compilador (si no entiendo algo completamente mal, soy nuevo en TS)
(El TypeScript utilizado en estos ejemplos está configurado por create-react-app, no cambié ninguna configuración)
Respuesta #1
Agrega "noUncheckedIndexedAccess": true a tu objeto compilerOptions en tsconfig.json
Respuesta #2
¿No debería el tipo ser number | undefined en su lugar porque puede ocurrir que una clave sea undefined?
Tienes esa opción si quieres; solo defínela como:
type MyType = {
[x: number] : number | undefined
}
Esto puede ser útil si esperas acceder a propiedades aleatorias que podrían no existir.
Por otro lado, sin embargo, es bastante común usar objetos de una manera más disciplinada que evita la posibilidad de acceder a propiedades inexistentes. Por ejemplo, si comúnmente estás escribiendo código que usa Object.keys(o) o for ... in para decidir qué propiedades acceder, entonces ya estás haciendo el trabajo para asegurarte de que existen, y puede llegar a ser frustrante que TypeScript siempre te diga que podría ser indefinido.
