typescript - property - error TS2339: la propiedad ''x'' no existe en el tipo ''Y''
property map does not exist on type observable response angular 6 (4)
No entiendo por qué este código genera un error de TypeScript. (No es el código original y es un poco derivado, por lo tanto, ignore el no sentido del ejemplo)
interface Images {
[key:string]: string;
}
function getMainImageUrl(images: Images): string {
return images.main;
}
Estoy recibiendo un error (usando TypeScript 1.7.5):
error TS2339: La propiedad ''principal'' no existe en el tipo ''Imágenes''.
Por supuesto que podría librarme del error al escribir:
return images["main"];
Preferiría no usar cadena para acceder a la propiedad. ¿Que puedo hacer?
La solución correcta es agregar la propiedad en la definición de tipo como se explica en la respuesta de @Nitzan Tomer. Si eso no es una opción sin embargo:
(Hacky) Solución 1
Puede asignar el objeto a una constante de tipo cualquiera y luego llamar a la propiedad ''no existente''.
const newObj: any = oldObj;
return newObj.someProperty;
También puedes lanzarlo como any
:
return (oldObj as any).someProperty;
Sin embargo, esto no proporciona ningún tipo de seguridad, que es el punto de TypeScript.
(Hacky) Solución 2
Otra cosa que puede considerar, si no puede modificar el tipo original, es extender el tipo así:
interface NewType extends OldType {
someProperty: string;
}
Ahora puedes lanzar tu variable como este NewType
lugar de any
. Aún no es ideal pero es menos permisivo que any
, lo que le brinda más seguridad de tipos.
return (oldObj as NewType).someProperty;
No soy un experto en Typescript, pero creo que el principal problema es la forma de acceder a los datos. Al ver cómo describió su interfaz de Images
, puede definir cualquier clave como una Cadena.
Al acceder a una propiedad, la sintaxis de "punto" ( images.main
) supone, creo, que ya existe. Tuve tales problemas sin Typescript, en Javascript "vainilla", donde intenté acceder a los datos como:
return json.property[0].index
donde el índice era una variable. Pero interpretó el index
, dando como resultado un:
cannot find property "index" of json.property[0]
Y tuve que encontrar una solución usando tu sintaxis:
return json.property[0][index]
Puede ser tu única opción allí. Pero, una vez más, no soy un experto en mecanografía, si alguien sabe una mejor solución / explicación sobre lo que sucede, siéntase libre de corregirme.
Se permite comenzar con TypeScript 2.2 usando notación de puntos para acceder a propiedades indexadas. No obtendrá el error TS2339 en su ejemplo.
Consulte Propiedad punteada para tipos con firmas de índice de cadena en la nota de versión de TypeScript 2.2 .
Si desea poder acceder a images.main
, debe definirlo explícitamente:
interface Images {
main: string;
[key:string]: string;
}
function getMainImageUrl(images: Images): string {
return images.main;
}
No puede acceder a las propiedades indexadas usando la notación de puntos porque mecanografia no tiene forma de saber si el objeto tiene esa propiedad o no.
Sin embargo, cuando define específicamente una propiedad, entonces el compilador sabe que está ahí (o no), sea opcional o no y cuál es el tipo.
Editar
Puedes tener una clase auxiliar para instancias de mapas, algo como:
class Map<T> {
private items: { [key: string]: T };
public constructor() {
this.items = Object.create(null);
}
public set(key: string, value: T): void {
this.items[key] = value;
}
public get(key: string): T {
return this.items[key];
}
public remove(key: string): T {
let value = this.get(key);
delete this.items[key];
return value;
}
}
function getMainImageUrl(images: Map<string>): string {
return images.get("main");
}
Tengo algo así implementado, y lo encuentro muy útil.