tipos sumar propiedades objeto herencia fundamentos datos clases typescript

sumar - typescript fundamentos



Error de TypeScript TS7015 al acceder a una enumeración utilizando un parámetro de tipo de cadena (4)

Soy nuevo en TypeScript y no comprendo qué debo hacer para corregir la línea que genera el error TS7015 (hacer referencia a un miembro de enumeración usando una variable de cadena) porque la línea que sigue inmediatamente no aparece (no hace referencia a un miembro de enum usando un literal de cadena):

enum State { Happy = 0, Sad = 1, Drunk = 2 } function Emote(enumKey:string) { console.log(State[enumKey]); // error TS7015: Element implicitly has an ''any'' type because index expression is not of type ''number''. console.log(State["Happy"]); // no error }

"noImplicitAny": true se establece en tsconfig.json del proyecto, se tsconfig.json el error

"noImplictAny": false se establece en el tsconfig.json del proyecto, no se detecta ningún error

Estoy compilando con "ntypescript": "^1.201603060104.1"

Ahora estoy compilando con "tsc": "1.8.10"

C:>npm install -g typescript `-- [email protected]

Verificando instalación:

C:/>tsc --version Version 1.8.10

Aquí está mi archivo tsconfig.json :

{ "compileOnSave": true, "compilerOptions": { "target": "ES5", "module": "System", "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": true, "noImplicitAny": true, "sourceMap": true, "mapRoot": "map/", "diagnostics": true }, "exclude": [ "node_modules", "typings" ] }

Aquí está la salida del compilador:

C:/>tsc test.ts(8,17): error TS7015: Element implicitly has an ''any'' type because index expression is not of type ''number''.


Puede evitar este error con la opción del compilador sin perder todas las verificaciones nulas estrictas

"suppressImplicitAnyIndexErrors": true


Si está utilizando TypeScript 2.1+, puede cambiar el tipo de keyof typeof State a keyof typeof State , como esto:

function Emote(enumKey: keyof typeof State) {...}

o, si se requiere que la entrada de la función sea una string , esto:

var state : State = State[enumKey as keyof typeof State];

Explicación:

El error se genera porque TypeScript, al ser una cadena arbitraria, no sabe si enumKey es el nombre de un miembro de State . TypeScript 2.1+ introdujo el operador keyof que devuelve una unión de los nombres de propiedad pública conocidos de un tipo. El uso de keyof nos permite afirmar que la propiedad está de hecho en el objeto de destino.

Sin embargo, cuando creas una enumeración, TypeScript produce tanto un tipo (que siempre es un subtipo de number ) como un valor (el objeto enum al que puedes hacer referencia en expresiones). Cuando escriba la keyof State , en realidad obtendrá una unión de los nombres de propiedad literales de number . Para obtener los nombres de propiedad del objeto enum, puede usar keyof typeof State .

Fuentes:

https://github.com/Microsoft/TypeScript/issues/13775#issuecomment-276381229 https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types


Sospecho que tiene que ver con el nuevo soporte de TS 1.8.x para literales de cadenas en estas situaciones. Sucede que TS sabe que "Happy" es un índice de cadena válido, pero no sabe si enumKey será o no. Puedes arreglarlo lanzándolo a un <any> , así:

function Emote(enumKey:string) { console.log(State[enumKey]); // error TS7015: Element implicitly has an ''any'' type because index expression is not of type ''number''. console.log(State["Melancholy"]); // error TS7015: Element implicitly has an ''any'' type because index expression is not of type ''number''. console.log(State["Happy"]); // no error console.log(State[<any>enumKey]); // no error console.log(State[<any>"Melancholy"]); // no error }

(Por cierto, creo que esto es nuevo: no pude reproducir este error con 1.8.9, pero tan pronto como actualicé a 1.8.10, pude).

También es interesante que hubiera esperado que esto funcionara sin el error, pero no lo hace:

function TypedEmote(enumKey:''Happy''|''Sad''|''Drunk''){ console.log(State[enumKey]); }

Debe ser algo sobre la especificación de TS que no entiendo, o tal vez simplemente no hayan logrado solucionar ese problema todavía.


var stateName = "Happy" var state = <State>parseInt(State[<any>stateName]);

Esto es lo que tuve que hacer para hacer feliz al compilador.