objetos - ¿Cómo puedo asignar dinámicamente propiedades a un objeto en TypeScript?
recorrer array de objetos javascript (15)
Si quisiera asignar programáticamente una propiedad a un objeto en Javascript, lo haría así:
var obj = {};
obj.prop = "value";
Pero en TypeScript, esto genera un error:
La propiedad ''prop'' no existe en el valor de tipo ''{}''
¿Cómo se supone que asignaré cualquier propiedad nueva a un objeto en TypeScript?
Almacene cualquier propiedad nueva en cualquier tipo de objeto encasillado en ''cualquiera'':
var extend = <any>myObject;
extend.NewProperty = anotherObject;
Más tarde, puedes recuperarlo volviendo tu objeto extendido a ''cualquiera'':
var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
Aunque el compilador se queja, todavía debería mostrarlo como lo requiera. Sin embargo, esto funcionará.
var s = {};
s[''prop''] = true;
Es posible agregar un miembro a un objeto existente por
- ampliando el tipo (léase: ampliar / especializar la interfaz)
- lanzar el objeto original al tipo extendido
- agregue el miembro al objeto
interface IEnhancedPromise<T> extends Promise<T> {
sayHello(): void;
}
const p = Promise.resolve("Peter");
const enhancedPromise = p as IEnhancedPromise<string>;
enhancedPromise.sayHello = () => enhancedPromise.then(value => console.info("Hello " + value));
// eventually prints "Hello Peter"
enhancedPromise.sayHello();
Es posible denotar obj
como any
, pero eso frustra el propósito total de usar mecanografiado. obj = {}
implica que obj
es un Object
. Marcarlo como any
no tiene sentido. Para lograr la coherencia deseada, una interfaz se puede definir de la siguiente manera.
interface LooseObject {
[key: string]: any
}
var obj: LooseObject = {};
O para hacerlo compacto:
var obj: {[k: string]: any} = {};
LooseObject
puede aceptar campos con cualquier cadena como clave y any
tipo como valor.
obj.prop = "value";
obj.prop2 = 88;
La verdadera elegancia de esta solución es que puede incluir campos seguros en la interfaz.
interface MyType {
typesafeProp1?: number,
requiredProp1: string,
[key: string]: any
}
var obj: MyType ;
obj = { requiredProp1: "foo"}; // valid
obj = {} // error. ''requiredProp1'' is missing
obj.typesafeProp1 = "bar" // error. typesafeProp1 should be a number
obj.prop = "value";
obj.prop2 = 88;
Esta solución es útil cuando su objeto tiene un Tipo específico. Al igual que cuando se obtiene el objeto a otra fuente.
let user: User = new User();
(user as any).otherProperty = ''hello'';
//user did not lose its type here.
La mejor práctica es usar mecanografía segura, te recomiendo:
interface customObject extends MyObject {
newProp: string;
newProp2: number;
}
O todo de una vez:
var obj:any = {}
obj.prop = 5;
Para garantizar que el tipo sea un Object
(es decir , pares clave-valor ), use:
const obj: {[x: string]: any} = {}
obj.prop = ''cool beans''
Para preservar tu tipo anterior, transfiere tu objeto temporalmente a cualquier
var obj = {}
(<any>obj).prop = 5;
La nueva propiedad dinámica solo estará disponible cuando uses el elenco:
var a = obj.prop; ==> Will generate a compiler error
var b = (<any>obj).prop; ==> Will assign 5 to b with no error;
Puede agregar esta declaración para silenciar las advertencias.
declare var obj: any;
Si está utilizando Typescript, presumiblemente quiere usar el tipo seguridad; en cuyo caso Objeto desnudo y ''cualquiera'' están contraindicados.
Es mejor no usar Object o {}, pero algunos tipos con nombre; o puede que esté utilizando una API con tipos específicos, que necesita ampliar con sus propios campos. He encontrado que esto funciona:
class Given { ... } // API specified fields; or maybe it''s just Object {}
interface PropAble extends Given {
props?: string; // you can cast any Given to this and set .props
// ''?'' indicates that the field is optional
}
let g:Given = getTheGivenObject();
(g as PropAble).props = "value for my new field";
// to avoid constantly casting:
let k:PropAble = getTheGivenObject();
k.props = "value for props";
Si puede usar las características JavaScript de ES6, puede usar los nombres de propiedad calculados para manejar esto muy fácilmente:
var req = {id : 0123456};
var response = {responses: {[req.id]: ''The 0123456 response message''}};
La clave de objeto [req.id] tiene un valor dinámico
Una opción más para hacerlo es acceder a la propiedad como una colección:
var obj = {};
obj[''prop''] = "value";
var foo:IFoo = <any>{};
a poner any
en el otro lado es decir var foo:IFoo = <any>{};
Entonces algo como esto sigue siendo seguro de tipo:
interface IFoo{
bar:string;
baz:string;
boo:string;
}
// How I tend to intialize
var foo:IFoo = <any>{};
foo.bar = "asdf";
foo.baz = "boo";
foo.boo = "boo";
// the following is an error,
// so you haven''t lost type safety
foo.bar = 123;
Alternativamente, puede marcar estas propiedades como opcionales:
interface IFoo{
bar?:string;
baz?:string;
boo?:string;
}
// Now your simple initialization works
var foo:IFoo = {};
asignar dinámicamente propiedades a un objeto en TypeScript.
para hacer eso solo necesitas usar interfaces de mecanografía así:
interface IValue {
prop1: string;
prop2: string;
}
interface IType {
[code: string]: IValue;
}
puedes usarlo así
var obj: IType = {};
obj[''code1''] = {
prop1: ''prop 1 value'',
prop2: ''prop 2 value''
};