Siempre compilo Typecript con la bandera --noImplicitAny. Esto tiene sentido ya que quiero que mi verificación de tipo sea lo más ajustada posible.
Mi problema es que con el siguiente código me sale el error Index signature of object type implicitly has an 'any' type
:
interface ISomeObject {
firstKey: string;
secondKey: string;
thirdKey: string;
}
let someObject: ISomeObject = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 'thirdValue'
};
let key: string = 'secondKey';
let secondValue: string = someObject[key];
Es importante tener en cuenta que la idea es que la variable clave proviene de otro lugar de la aplicación y puede ser cualquiera de las claves del objeto.
He intentado emitir explícitamente el tipo por:
let secondValue: string = <string>someObject[key];
¿O es que mi escenario simplemente no es posible --noImplicitAny
?
fuente
Otra forma de evitar el error es usar el elenco de esta manera:
let secondValue: string = (<any>someObject)[key];
(Tenga en cuenta el paréntesis)El único problema es que esto ya no es de tipo seguro, como lo está haciendo
any
. Pero siempre puedes volver al tipo correcto.ps: estoy usando el mecanografiado 1.7, no estoy seguro acerca de las versiones anteriores.
fuente
let secondValue: string = (someObject as any)[key];
TypeScript 2.1 introdujo una forma elegante de manejar este problema.
Podemos acceder a todos los nombres de propiedades del objeto durante la fase de compilación por
keyof
palabra clave (ver el registro de cambios ).Solo necesita reemplazar el
string
tipo de variable conkeyof ISomeObject
. Ahora el compilador sabe que lakey
variable solo puede contener nombres de propiedadesISomeObject
.Ejemplo completo:
Código en vivo en typescriptlang.org (establecer
noImplicitAny
opción)Lectura adicional con más
keyof
usos .fuente
key
comoconst key = (keyof ISomeObject)
= 'segundo' + 'Clave'La siguiente configuración de tsconfig le permitirá ignorar estos errores: configúrelo como verdadero.
fuente
--noImplicitAny
. Combina perfectamente la pregunta de op.XMLHttpRequest
.keyof
operador TS2.1 puede ayudar a mantener todo estricto, ¡vea la respuesta de Piotr!La solución 'keyof' mencionada anteriormente funciona. Pero si la variable se usa solo una vez, por ejemplo, recorrer un objeto, etc., también puede escribirla.
fuente
utilizar
keyof typeof
fuente
Similar a la respuesta de @Piotr Lewandowski, pero dentro de un
forEach
:fuente
Argument of type '(field: "id" | "url" | "name") => void' is not assignable to parameter of type '(value: string, index: number, array: string[]) => void'
. Mi código se ve asíObject.keys(components).forEach((comp: Component) => {...}
, dondeComponent
es un tipo (comoMyConfig
).Declara el objeto así.
fuente
Sin indexador? ¡Entonces haz el tuyo!
Globalmente he definido esto como una manera fácil de definir una firma de objeto.
T
puede serany
si es necesario:Solo agrego
indexer
como miembro de la clase.Así que termino con esto:
La ventaja de hacer esto es que recupera el tipo correcto: muchas de las soluciones que usa
<any>
perderán el tipeo por usted. Recuerde que esto no realiza ninguna verificación de tiempo de ejecución. Aún deberá comprobar si existe algo si no sabe con certeza si existe.Si desea ser demasiado cauteloso, y lo está utilizando
strict
, puede hacer esto para revelar todos los lugares que puede necesitar para hacer una verificación explícita indefinida:Por lo general, no encuentro esto necesario ya que si tengo como propiedad de cadena de algún lugar, generalmente sé que es válido.
Este método me ha resultado especialmente útil si tengo mucho código que necesita para acceder al indexador, y la escritura se puede cambiar en un solo lugar.
Nota: Estoy usando el
strict
modo, yunknown
definitivamente es necesario.El código compilado simplemente será
indexer = this
, por lo que es muy similar a cuando el mecanografiado crea_this = this
para usted.fuente
Record<T>
tipo de letra; en este momento no puedo investigar los detalles finos de esto, pero para algunos casos limitados puede funcionar mejor.Crear una interfaz para definir la interfaz 'indexador'
Luego crea tu objeto con ese índice.
Nota: esto seguirá teniendo los mismos problemas que otras respuestas han descrito con respecto a la aplicación del tipo de cada elemento, pero a menudo eso es exactamente lo que desea.
Puede hacer que el parámetro de tipo genérico sea lo que necesite:
ObjectIndexer< Dog | Cat>
Zona de juegos mecanografiada
Incluso puede usar esto en una restricción genérica al definir un tipo genérico:
export class SmartFormGroup<T extends IndexableObject<any>> extends FormGroup
Luego
T
dentro de la clase se puede indexar :-)fuente
Dictionary
que represente{ [key: string]: T }
, pero si la hay, edite esta pregunta para eliminar miObjectIndexer
.Declare el tipo cuya clave es string y el valor puede ser cualquiera, luego declare el objeto con este tipo y la pelusa no aparecerá
Entonces tu código será
fuente
En la actualidad, la mejor solución es declarar tipos. Me gusta
fuente
La solución más simple que pude encontrar usando el Script 3.1 en 3 pasos es:
1) Hacer interfaz
2) Hacer una copia mecanografiada
3) Usar en cualquier lugar (JSX incluido)
fuente