Hoe kan ik dynamische eigenschappen toewijzen aan een object met de schrijfmachine?

stemmen
129

Als ik wilde een woning aan een object in Javascript programmatisch toewijzen, dan zou ik het doen like this:

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

Maar in typoscript, dit genereert een foutmelding:

Het pand 'prop' bestaat niet op de waarde van het type '{}'

Hoe moet ik een nieuw pand op een object met de schrijfmachine toe te wijzen?

De vraag is gesteld op 03/10/2012 om 15:42
bron van user
In andere talen...                            


21 antwoorden

stemmen
111

Er kunnen duiden objals any, maar dat verslaat het hele doel van het gebruik schrijfmachine. obj = {}impliceert objis Object. Te markeren als anygeen zin heeft. De gewenste consistentie interface kan als volgt worden omschreven bereiken.

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};

Of om het compact te maken:

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

LooseObjectkan velden met willekeurige tekenreeks als sleutel te accepteren en anytyp als waarde.

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

De echte elegantie van deze oplossing is dat je Typesafe velden in de interface kan bevatten.

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;
antwoordde op 08/06/2017 om 16:32
bron van user

stemmen
61

Of alles in één keer:

  var obj:any = {}
  obj.prop = 5;
antwoordde op 03/10/2012 om 16:51
bron van user

stemmen
45

Ik heb de neiging om te zetten anyaan de andere kant dat wil zeggen var foo:IFoo = <any>{};dus iets als dit is nog steeds 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; 

Als alternatief kunt u deze eigenschappen als optie te markeren:

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

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

Probeer het online

antwoordde op 26/08/2013 om 13:32
bron van user

stemmen
24

Deze oplossing is handig wanneer uw object heeft specifiek type. Zoals bij het verkrijgen van het object andere bron.

let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
antwoordde op 25/08/2016 om 08:51
bron van user

stemmen
21

Hoewel de compiler klaagt het moet nog steeds de uitgang als u nodig heeft. Dit zal echter werken.

var s = {};
s['prop'] = true;
antwoordde op 03/10/2012 om 15:57
bron van user

stemmen
14

Nog een optie te doen om dat is om toegang te krijgen tot het pand als een verzameling:

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

antwoordde op 22/03/2017 om 13:23
bron van user

stemmen
4

Om te garanderen dat het type is een Object(dwz key-value paren ), te gebruiken:

const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'
antwoordde op 16/06/2017 om 14:15
bron van user

stemmen
3

De best practice is gebruik maken van veilig typen, ik u aanbevelen:

interface customObject extends MyObject {
   newProp: string;
   newProp2: number;
}
antwoordde op 11/10/2016 om 23:32
bron van user

stemmen
2
  • Zaak 1:

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

  • Case 2:

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

antwoordde op 12/01/2019 om 15:45
bron van user

stemmen
2

Om uw vorige soort te behouden, tijdelijke cast uw object aan een

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

De nieuwe dynamische eigenschap is alleen beschikbaar wanneer u de cast te gebruiken:

  var a = obj.prop; ==> Will generate a compiler error
  var b = (<any>obj).prop; ==> Will assign 5 to b with no error;
antwoordde op 09/12/2016 om 16:44
bron van user

stemmen
2

Bewaar geen nieuwe woning op elk soort object door typecasting aan 'elke':

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

Later, kunt u deze opvragen door het gieten van uw uitgebreide object terug naar 'elke':

var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
antwoordde op 25/11/2015 om 13:21
bron van user

stemmen
2

U kunt deze verklaring aan de waarschuwingen zwijgen toe te voegen.

declare var obj: any;

antwoordde op 03/10/2012 om 16:02
bron van user

stemmen
1

Ik ben verrast dat geen van de antwoorden verwijzen Object.assign want dat is de techniek die ik gebruiken wanneer ik denk aan "compositie" in JavaScript.

En het werkt zoals verwacht in typoscript:

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

voordelen

  • Typ veiligheid in, omdat je niet nodig om het te gebruiken anysoort helemaal
  • maakt gebruik van aggregaat type typescript's (zoals aangegeven door de &bij het declareren van het type objectWithAllProps), die duidelijk communiceert dat we het samenstellen van een nieuw type on-the-fly (dwz dynamisch)

Dingen bewust te zijn van

  1. Object.assign heeft zijn eigen unieke aspecten (die bekend zijn bij de meeste ervaren JS devs) dat moet worden overwogen bij het schrijven typoscript.
    • Het kan gebruikt worden in een veranderlijke mode, of een onveranderlijke wijze (I demonstreren de onveranderlijke ver boven, wat betekent dat existingObjectblijft onaangeroerd en dus niet een hebben emailonroerend goed. Voor de meeste functionele stijl programmeurs, dat is een goede zaak, omdat het resultaat is de enige nieuwe verandering).
    • Object.assign het beste werkt als je vlakker objecten. Als u het combineren van twee geneste objecten die nullable eigenschappen bevatten, kan je uiteindelijk het overschrijven truthy waarden ongedefinieerd. Als je kijk uit voor de volgorde van de Object.assign argumenten, moet je wel goed.
antwoordde op 30/01/2019 om 16:21
bron van user

stemmen
1

Het is mogelijk om een ​​lid van een bestaand object voeg

  1. verbreding type (lees: breiden / gespecialiseerd interface)
  2. wierp het originele object het uitgebreide Type
  3. voeg het lid aan het object
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();
antwoordde op 08/03/2018 om 11:20
bron van user

stemmen
1

Als u gebruik maakt Typescript, waarschijnlijk wilt u het type veiligheid te gebruiken; in welk geval naakte Object en 'elke' worden counterindicated.

Beter niet te gebruiken Object of {}, maar sommige noemde type; of u zou kunnen worden met behulp van een API met specifieke soorten, die je nodig hebt uit te breiden met uw eigen velden. Ik heb gemerkt dat dit werk:

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";
antwoordde op 02/01/2018 om 03:07
bron van user

stemmen
1

dynamische eigenschappen toewijzen aan een object schrijfmachine.

om dat te doen Je hoeft alleen maar typoscript interfaces te gebruiken als volgt:

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

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

je kunt het gebruiken als dat

var obj: IType = {};
obj['code1'] = { 
                 prop1: 'prop 1 value', 
                 prop2: 'prop 2 value' 
               };
antwoordde op 30/03/2017 om 04:31
bron van user

stemmen
0

U kunt dit gebruiken:

this.model = Object.assign(this.model, { newProp: 0 });
antwoordde op 09/07/2019 om 23:53
bron van user

stemmen
0

U kunt een nieuw object te maken op basis van het oude object met behulp van de verspreiding operator

interface MyObject {
    prop1: string;
}

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

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

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

Typoscript zal alle velden van het oorspronkelijke object afleiden en VSCode zal automatisch aanvullen te doen, enz.

antwoordde op 10/06/2019 om 01:59
bron van user

stemmen
0

Eenvoudigste zal volgen

const obj = <any>{};
obj.prop1 = "value";
obj.prop2 = "another value"
antwoordde op 02/05/2019 om 23:18
bron van user

stemmen
0

javascript:

myObj.myProperty = 1;

typescript:

myObj['myProperty'] = 1;
antwoordde op 09/02/2019 om 09:43
bron van user

stemmen
-1

Als u in staat om ES6 JavaScript-functies te gebruiken, kunt u gebruik maken van Computed Property Namen om dit te verwerken heel gemakkelijk:

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

De [req.id] toets object een dynamische waarde

antwoordde op 16/01/2018 om 11:03
bron van user

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