Come posso assegnare dynamicmente le proprietà a un object in TypeScript?

Se volessi assegnare programmaticamente una proprietà a un object in Javascript, lo farei in questo modo:

var obj = {}; obj.prop = "value"; 

Ma in TypeScript, questo genera un errore:

La proprietà “prop” non esiste sul valore di tipo “{}”

Come dovrei assegnare una nuova proprietà a un object in TypeScript?

È ansible denotare obj come any , ma ciò vanifica l’intero scopo dell’uso del typescript. obj = {} implica obj è un Object . Marcarlo come any non ha senso. Per ottenere la consistenza desiderata, un’interfaccia potrebbe essere definita come segue.

 interface LooseObject { [key: string]: any } var obj: LooseObject = {}; 

O per renderlo compatto:

 var obj: {[k: string]: any} = {}; 

LooseObject può accettare campi con qualsiasi stringa come chiave e any tipo come valore.

 obj.prop = "value"; obj.prop2 = 88; 

La vera eleganza di questa soluzione è che puoi includere campi tipografici nell’interfaccia.

 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; 

O tutto in una volta:

  var obj:any = {} obj.prop = 5; 

Tendo a mettere any altro lato vale a dire var foo:IFoo = {}; Quindi qualcosa di simile è ancora typescript:

 interface IFoo{ bar:string; baz:string; boo:string; } // How I tend to intialize var foo:IFoo = {}; foo.bar = "asdf"; foo.baz = "boo"; foo.boo = "boo"; // the following is an error, // so you haven't lost type safety foo.bar = 123; 

In alternativa è ansible contrassegnare queste proprietà come facoltative:

 interface IFoo{ bar?:string; baz?:string; boo?:string; } // Now your simple initialization works var foo:IFoo = {}; 

Provalo online

Questa soluzione è utile quando il tuo object ha un tipo specifico. Come quando si ottiene l’object su un’altra fonte.

 let user: User = new User(); (user as any).otherProperty = 'hello'; //user did not lose its type here. 

Sebbene il compilatore si lamenti, dovrebbe comunque produrlo come richiesto. Tuttavia, funzionerà.

 var s = {}; s['prop'] = true; 

Un’altra opzione è quella di accedere alla proprietà come una raccolta:

 var obj = {}; obj['prop'] = "value"; 

Per garantire che il tipo sia un Object (cioè coppie chiave-valore ), utilizzare:

 const obj: {[x: string]: any} = {} obj.prop = 'cool beans' 

È ansible aggiungere questa dichiarazione per silenziare gli avvertimenti.

declare var obj: any;

La migliore pratica è usare la digitazione sicura, ti raccomando:

 interface customObject extends MyObject { newProp: string; newProp2: number; } 

Memorizza qualsiasi nuova proprietà su qualsiasi tipo di object digitandolo a “any”:

 var extend = myObject; extend.NewProperty = anotherObject; 

In seguito puoi recuperarlo rimandando l’object esteso a “qualsiasi”:

 var extendedObject = myObject; var anotherObject = extendedObject.NewProperty; 

Per conservare il tuo tipo precedente, lancia temporaneamente il tuo object su qualsiasi

  var obj = {} (obj).prop = 5; 

La nuova proprietà dynamic sarà disponibile solo quando si utilizza il cast:

  var a = obj.prop; ==> Will generate a compiler error var b = (obj).prop; ==> Will assign 5 to b with no error; 

Se stai usando Typescript, presumibilmente vuoi usare il tipo safety; nel qual caso l’object nudo e “qualsiasi” sono controindicati.

Meglio non usare Object o {}, ma un certo tipo di nome; oppure potresti utilizzare un’API con tipi specifici, che devi estendere con i tuoi campi. Ho trovato questo funziona:

 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"; 

È ansible aggiungere un membro a un object esistente tramite

  1. allargando il tipo (leggi: estendi / specializza l’interfaccia)
  2. lancia l’object originale nel tipo esteso
  3. aggiungi il membro all’object
 interface IEnhancedPromise extends Promise { sayHello(): void; } const p = Promise.resolve("Peter"); const enhancedPromise = p as IEnhancedPromise; enhancedPromise.sayHello = () => enhancedPromise.then(value => console.info("Hello " + value)); // eventually prints "Hello Peter" enhancedPromise.sayHello(); 

assegnare dynamicmente le proprietà a un object in TypeScript.

per farlo basta usare le interfacce dattiloscritte in questo modo:

 interface IValue { prop1: string; prop2: string; } interface IType { [code: string]: IValue; } 

puoi usarlo così

 var obj: IType = {}; obj['code1'] = { prop1: 'prop 1 value', prop2: 'prop 2 value' }; 

Se sei in grado di utilizzare le funzionalità JavaScript di ES6, puoi utilizzare i nomi di proprietà calcolati per gestirli molto facilmente:

 var req = {id : 0123456}; var response = {responses: {[req.id]: 'The 0123456 response message'}}; 

La chiave dell’object [req.id] ha un valore dinamico