Cum pot atribui dinamic proprietățile unui obiect dactilografiat?

voturi
129

Dacă aș fi vrut să atribuie o proprietate prin programare un obiect în Javascript, aș face place acest lucru:

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

Dar dactilografiat, acest lucru generează o eroare:

Proprietatea „prop“ nu exista pe valoarea de tip „{}“

Cum ar trebui să atribuie orice proprietate nouă la un obiect dactilografiat?

Întrebat 03/10/2012 la 15:42
sursa de către utilizator
În alte limbi...                            


21 răspunsuri

voturi
111

Este posibil să denote objca any, dar care zădărnicește întregul scop de a folosi dactilografiate. obj = {}implică objo Object. Marcându - l ca anynu are sens. Pentru a realiza consistența dorită o interfață poate fi definită după cum urmează.

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};

SAU pentru a face compact:

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

LooseObjectpoate accepta câmpuri cu orice șir de caractere ca și cheie de anytip ca valoare.

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

Eleganța reală a acestei soluții este că puteți include typesafe câmpuri în interfața.

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;
Publicat 08/06/2017 la 16:32
sursa de către utilizator

voturi
61

Sau toate într-un du-te:

  var obj:any = {}
  obj.prop = 5;
Publicat 03/10/2012 la 16:51
sursa de către utilizator

voturi
45

Am tendința de a pune anype cealaltă parte și anume var foo:IFoo = <any>{};Deci , ceva de genul acesta este încă 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; 

Alternativ, puteți marca aceste proprietăți ca opționale:

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

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

Încercați-l on-line

Publicat 26/08/2013 la 13:32
sursa de către utilizator

voturi
24

Această soluție este utilă atunci când obiectul are tip specific. Ca și în cazul obținerii obiectului la o altă sursă.

let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
Publicat 25/08/2016 la 08:51
sursa de către utilizator

voturi
21

Deși compilatorul se plânge că ar trebui încă de ieșire-l ca ai nevoie. Cu toate acestea, acest lucru va funcționa.

var s = {};
s['prop'] = true;
Publicat 03/10/2012 la 15:57
sursa de către utilizator

voturi
14

O opțiune mai face pentru că este de a avea acces la proprietatea ca o colecție:

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

Publicat 22/03/2017 la 13:23
sursa de către utilizator

voturi
4

Pentru a garanta că tipul este un Object(adică perechile cheie-valoare ), utilizați:

const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'
Publicat 16/06/2017 la 14:15
sursa de către utilizator

voturi
3

Cea mai bună practică este de a utiliza tastarea în condiții de siguranță, va recomand:

interface customObject extends MyObject {
   newProp: string;
   newProp2: number;
}
Publicat 11/10/2016 la 23:32
sursa de către utilizator

voturi
2
  • Cazul 1:

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

  • Cazul 2:

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

Publicat 12/01/2019 la 15:45
sursa de către utilizator

voturi
2

Pentru a păstra tipul anterior, exprimate temporar obiect la orice

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

Noua proprietate dinamică va fi disponibilă numai atunci când utilizați exprimate:

  var a = obj.prop; ==> Will generate a compiler error
  var b = (<any>obj).prop; ==> Will assign 5 to b with no error;
Publicat 09/12/2016 la 16:44
sursa de către utilizator

voturi
2

Stocați orice proprietate nouă pe orice fel de obiect de typecasting-l la „orice“:

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

Mai târziu îl puteți recupera prin turnare obiectului extins înapoi la „orice“:

var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
Publicat 25/11/2015 la 13:21
sursa de către utilizator

voturi
2

Puteți adăuga această declarație pentru a opri avertismentele.

declare var obj: any;

Publicat 03/10/2012 la 16:02
sursa de către utilizator

voturi
1

Sunt surprins de faptul că nici unul dintre răspunsurile de referință Object.assign deoarece aceasta este tehnica am folosi ori de câte ori mă gândesc la „compoziție“, în JavaScript.

Și funcționează cum era de așteptat dactilografiat:

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

avantaje

  • tip de siguranță pe tot parcursul , deoarece nu trebuie să utilizați anytipul de la toate
  • folosește tipul typescript lui agregat (așa cum rezultă &atunci când declararea tipului de objectWithAllProps), care comunică în mod clar că vom compune un nou tip on-the-fly ( de exemplu , în mod dinamic)

Lucrurile să fie conștienți de

  1. Object.assign are este unic aspecte proprii (care sunt bine cunoscute de cele mai multe devs JS cu experiență), care ar trebui să fie luate în considerare atunci când scrieți dactilografiate.
    • Acesta poate fi utilizat într - o manieră mutabil, sau un mod imuabil (I demonstrează modul în care imuabil de mai sus, ceea ce înseamnă că existingObjectrămâne neatins și , prin urmare , nu are o emailproprietate. Pentru majoritatea programatori stil funcțional, care este un lucru bun , deoarece rezultatul este singura modificare nouă).
    • Object.assign funcționează cel mai bine atunci când aveți obiecte plate. Dacă se combină două obiecte imbricate care contin proprietati poate fi nulă, puteți ajunge suprascrierea valori truthy cu nedefinită. Daca ai grija pentru ordinea argumentelor Object.assign, ar trebui să fie bine.
Publicat 30/01/2019 la 16:21
sursa de către utilizator

voturi
1

Este posibil să se adauge un membru la un obiect existent

  1. lărgirea tipul (citește: extinde / specializa interfața)
  2. exprimate obiectul original cu tipul extins
  3. adaugă membrul la obiect
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();
Publicat 08/03/2018 la 11:20
sursa de către utilizator

voturi
1

Dacă utilizați typescript, probabil doriți să utilizați siguranța de tip; în care caz obiect gol și „orice“ sunt counterindicated.

Mai bine să nu folosească Object sau {}, dar un anumit tip pe nume; sau este posibil să utilizați un API cu tipuri specifice, pe care trebuie prelungi cu propriile câmpuri. Am găsit acest lucru la locul de muncă:

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";
Publicat 02/01/2018 la 03:07
sursa de către utilizator

voturi
1

atribuie dinamic proprietăți la un obiect dactilografiat.

pentru a face asta ai nevoie doar de a utiliza interfețe typescript astfel:

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

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

îl puteți folosi așa

var obj: IType = {};
obj['code1'] = { 
                 prop1: 'prop 1 value', 
                 prop2: 'prop 2 value' 
               };
Publicat 30/03/2017 la 04:31
sursa de către utilizator

voturi
0

puteți utiliza acest lucru:

this.model = Object.assign(this.model, { newProp: 0 });
Publicat 09/07/2019 la 23:53
sursa de către utilizator

voturi
0

Puteți crea un nou obiect bazat pe obiect vechi, cu ajutorul operatorului de răspândire

interface MyObject {
    prop1: string;
}

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

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

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

Typescript va deduce toate domeniile obiectului original și VSCode va face autocompletare, etc.

Publicat 10/06/2019 la 01:59
sursa de către utilizator

voturi
0

Va fi următoarea simplă

const obj = <any>{};
obj.prop1 = "value";
obj.prop2 = "another value"
Publicat 02/05/2019 la 23:18
sursa de către utilizator

voturi
0

Javascript:

myObj.myProperty = 1;

typescript:

myObj['myProperty'] = 1;
Publicat 09/02/2019 la 09:43
sursa de către utilizator

voturi
-1

Dacă sunteți capabil de a utiliza funcțiile ES6 JavaScript, puteți utiliza denumiri de proprietate computerizata pentru a gestiona foarte ușor acest lucru:

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

Sau [req.id] Cheia obiect are o valoare dinamică

Publicat 16/01/2018 la 11:03
sursa de către utilizator

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