Come posso assegnare dinamicamente le proprietà a un oggetto a macchina?

voti
129

Se avessi voluto assegnare programatically una proprietà da un oggetto in Javascript, lo farei in questo modo:

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

Ma a macchina, questo genera un errore:

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

Come faccio a assegnare qualsiasi nuova proprietà a un oggetto a macchina?

È pubblicato 03/10/2012 alle 15:42
fonte dall'utente
In altre lingue...                            


21 risposte

voti
111

E 'possibile indicare objcome any, ma che sconfigge l'intero scopo di utilizzare dattiloscritto. obj = {}implica objè una Object. Marcatura come anynon ha senso. Per realizzare la consistenza desiderata un'interfaccia potrebbe essere definito come segue.

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};

O per rendere più compatta:

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

LooseObjectpuò accettare campi con qualsiasi stringa come chiave e anydigitare come valore.

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

La vera eleganza di questa soluzione è che è possibile includere typesafe campi 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;
Risposto il 08/06/2017 a 16:32
fonte dall'utente

voti
61

O tutti in una volta:

  var obj:any = {}
  obj.prop = 5;
Risposto il 03/10/2012 a 16:51
fonte dall'utente

voti
45

Io tendo a mettere anysul lato opposto cioè var foo:IFoo = <any>{};Quindi qualcosa di simile a questo è ancora typesafe:

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; 

In alternativa è possibile contrassegnare queste proprietà come optional:

interface IFoo{
    bar?:string;
    baz?:string;
    boo?:string;    
}

// Now your simple initialization works
var foo:IFoo = {};

Provalo in rete

Risposto il 26/08/2013 a 13:32
fonte dall'utente

voti
24

Questa soluzione è utile quando l'oggetto è di tipo specifico. Come quando ottenere l'oggetto da altra fonte.

let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
Risposto il 25/08/2016 a 08:51
fonte dall'utente

voti
21

Anche se il compilatore si lamenta dovrebbe ancora uscita come si richiede. Tuttavia, questo funzionerà.

var s = {};
s['prop'] = true;
Risposto il 03/10/2012 a 15:57
fonte dall'utente

voti
14

Una possibilità più che fare per è quello di accedere alla proprietà come una collezione:

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

Risposto il 22/03/2017 a 13:23
fonte dall'utente

voti
4

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

const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'
Risposto il 16/06/2017 a 14:15
fonte dall'utente

voti
3

La pratica migliore è usare la tipizzazione sicuro, vi consiglio:

interface customObject extends MyObject {
   newProp: string;
   newProp2: number;
}
Risposto il 11/10/2016 a 23:32
fonte dall'utente

voti
2
  • Caso 1:

    var car = {type: "BMW", model: "i8", color: "white"}; car['owner'] = "ibrahim"; // You can add a property:

  • Caso 2:

    var car:any = {type: "BMW", model: "i8", color: "white"}; car.owner = "ibrahim"; // You can set a property: use any type

Risposto il 12/01/2019 a 15:45
fonte dall'utente

voti
2

Per preservare il tipo precedente, il cast temporanea l'oggetto a qualsiasi

  var obj = {}
  (<any>obj).prop = 5;

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

  var a = obj.prop; ==> Will generate a compiler error
  var b = (<any>obj).prop; ==> Will assign 5 to b with no error;
Risposto il 09/12/2016 a 16:44
fonte dall'utente

voti
2

Memorizzare qualsiasi nuova proprietà su qualsiasi tipo di oggetto typecasting a 'qualsiasi':

var extend = <any>myObject;
extend.NewProperty = anotherObject;

In seguito è possibile recuperarlo lanciando l'oggetto esteso di nuovo a 'qualsiasi':

var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
Risposto il 25/11/2015 a 13:21
fonte dall'utente

voti
2

È possibile aggiungere questa dichiarazione per mettere a tacere gli avvertimenti.

declare var obj: any;

Risposto il 03/10/2012 a 16:02
fonte dall'utente

voti
1

Sono sorpreso che nessuna delle risposte riferimento Object.assign dato che è la tecnica che uso ogni volta che penso a "composizione" in JavaScript.

E funziona come previsto a macchina:

interface IExisting {
    userName: string
}

interface INewStuff {
    email: string
}

const existingObject: IExisting = {
    userName: "jsmith"
}

const objectWithAllProps: IExisting & INewStuff = Object.assign({}, existingObject, {
    email: "jsmith@someplace.com"
})

console.log(objectWithAllProps.email); // jsmith@someplace.com

vantaggi

  • Tipo di sicurezza in tutta perché non è necessario utilizzare il anytipo a tutti
  • utilizza il tipo di dattiloscritto aggregato (come indicato dal &quando dichiara il tipo di objectWithAllProps), che comunica chiaramente che stiamo comporre un nuovo tipo on-the-fly (cioè dinamicamente)

Le cose da tenere presente

  1. Object.assign ha le sue proprie aspetti unici (che sono ben noti per la maggior parte degli sviluppatori esperti JS) che dovrebbero essere considerati quando si scrive dattiloscritto.
    • Può essere utilizzato in modo mutevole, o un modo immutabile (I dimostrare il modo immutabile, sopra, il che significa che existingObjectrimane intatta e, pertanto, non ha un emailimmobile. Per la maggior parte dei programmatori funzionali in stile, che è una buona cosa in quanto il risultato è l'unico nuovo cambiamento).
    • Object.assign funziona meglio quando si hanno oggetti più piatte. Se si combinano due oggetti nidificati che contengono proprietà nullable, si può finire per sovrascrivere i valori truthy con indefinito. Se si guarda fuori per l'ordine degli argomenti Object.assign, si dovrebbe andare bene.
Risposto il 30/01/2019 a 16:21
fonte dall'utente

voti
1

È possibile aggiungere un elemento a un oggetto esistente

  1. allargando il tipo (leggi: estensione / specializzare l'interfaccia)
  2. cast dell'oggetto originale al tipo esteso
  3. aggiungere il membro all'oggetto
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();
Risposto il 08/03/2018 a 11:20
fonte dall'utente

voti
1

Se si utilizza tipografico, presumibilmente si desidera utilizzare la sicurezza tipo; nel qual caso oggetto nudo e 'qualsiasi' sono counterindicated.

Meglio non usare per oggetto o {}, ma un certo tipo di nome; o si potrebbero utilizzare un'API con tipi specifici, che è necessario estendere con i propri campi. Ho trovato questo per il lavoro:

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";
Risposto il 02/01/2018 a 03:07
fonte dall'utente

voti
1

assegnare dinamicamente le proprietà di un oggetto a macchina.

Per fare questo è sufficiente utilizzare le interfacce dattiloscritto in questo modo:

interface IValue {
    prop1: string;
    prop2: string;
}

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

è possibile utilizzarlo come quella

var obj: IType = {};
obj['code1'] = { 
                 prop1: 'prop 1 value', 
                 prop2: 'prop 2 value' 
               };
Risposto il 30/03/2017 a 04:31
fonte dall'utente

voti
0

è possibile utilizzare questo:

this.model = Object.assign(this.model, { newProp: 0 });
Risposto il 09/07/2019 a 23:53
fonte dall'utente

voti
0

È possibile creare un nuovo oggetto sulla base del vecchio oggetto utilizzando l'operatore diffusione

interface MyObject {
    prop1: string;
}

const myObj: MyObject = {
    prop1: 'foo',
}

const newObj = {
    ...myObj,
    prop2: 'bar',
}

console.log(newObj.prop2); // 'bar'

Dattiloscritto sarà dedurre tutti i campi dell'oggetto originale e VSCode farà il completamento automatico, ecc

Risposto il 10/06/2019 a 01:59
fonte dall'utente

voti
0

Più semplice sarà seguendo

const obj = <any>{};
obj.prop1 = "value";
obj.prop2 = "another value"
Risposto il 02/05/2019 a 23:18
fonte dall'utente

voti
0

Javascript:

myObj.myProperty = 1;

Dattiloscritto:

myObj['myProperty'] = 1;
Risposto il 09/02/2019 a 09:43
fonte dall'utente

voti
-1

Se siete in grado di utilizzare le funzioni ES6 JavaScript, è possibile utilizzare calcolate Nomi proprietà per gestire questo molto facilmente:

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

La chiave oggetto [req.id] ha un valore dinamico

Risposto il 16/01/2018 a 11:03
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more