Wie dynamisch zuweisen I Eigenschaften zu einem Objekt in Typoskript?

stimmen
129

Wenn ich eine Eigenschaft auf ein Objekt in Javascript programmatisch zuweisen wollte, würde ich dies tun, es mag:

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

Aber in Typoskript, erzeugt dies einen Fehler:

Die Eigenschaft ‚prop‘ existiert nicht auf Wert vom Typ ‚{}‘

Wie bin ich eine neue Eigenschaft auf ein Objekt in Typoskript zuweisen soll?

Veröffentlicht am 03/10/2012 um 15:42
quelle vom benutzer
In anderen Sprachen...                            


21 antworten

stimmen
111

Es ist möglich , zu bezeichnen , objwie any, aber das Niederlage des ganzen Zwecks der Typoskript mit. obj = {}impliziert objein Object. Kennzeichnung als anykeinen Sinn macht. Um das erreichen kann die gewünschte Konsistenz eine Schnittstelle wie folgt definiert werden.

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};

Oder um es kompakt zu machen:

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

LooseObjectkann als Schlüsselfeld mit einem beliebigen Zeichenkette übernehmen und anyals Wert eingeben.

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

Die wirkliche Eleganz dieser Lösung ist, dass Sie typsichere Felder in der Schnittstelle enthalten.

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;
Beantwortet am 08/06/2017 um 16:32
quelle vom benutzer

stimmen
61

Oder alles in einem Rutsch:

  var obj:any = {}
  obj.prop = 5;
Beantwortet am 03/10/2012 um 16:51
quelle vom benutzer

stimmen
45

Ich neige dazu bringen anyauf der anderen Seite , dh var foo:IFoo = <any>{};also so etwas wie das ist immer noch typsicher:

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 können Sie diese Eigenschaften als optional markieren:

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

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

Versuchen Sie es online

Beantwortet am 26/08/2013 um 13:32
quelle vom benutzer

stimmen
24

Diese Lösung ist nützlich, wenn Ihr Objekt Arttypisch hat. Wie, wenn das Objekt zu einem anderen Quelle zu erhalten.

let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
Beantwortet am 25/08/2016 um 08:51
quelle vom benutzer

stimmen
21

Obwohl der Compiler beschwert sollte es noch gibt es, wie Sie benötigen. Dies wird jedoch funktionieren.

var s = {};
s['prop'] = true;
Beantwortet am 03/10/2012 um 15:57
quelle vom benutzer

stimmen
14

Eine weitere Option, das zu tun ist, um die Eigenschaft als eine Sammlung zuzugreifen:

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

Beantwortet am 22/03/2017 um 13:23
quelle vom benutzer

stimmen
4

Um zu gewährleisten , dass der Typ ein Object(dh Schlüsselwertpaaren ), verwendet werden :

const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'
Beantwortet am 16/06/2017 um 14:15
quelle vom benutzer

stimmen
3

Die beste Vorgehensweise ist sicher Typisierung, empfehle ich Ihnen:

interface customObject extends MyObject {
   newProp: string;
   newProp2: number;
}
Beantwortet am 11/10/2016 um 23:32
quelle vom benutzer

stimmen
2
  • Fall 1:

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

  • Fall 2:

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

Beantwortet am 12/01/2019 um 15:45
quelle vom benutzer

stimmen
2

Um Ihre vorherige Art, temporäre Besetzung Ihr Objekts zu einem wahren

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

Die neue dynamische Eigenschaft ist nur dann verfügbar sein, wenn Sie die Besetzung verwenden:

  var a = obj.prop; ==> Will generate a compiler error
  var b = (<any>obj).prop; ==> Will assign 5 to b with no error;
Beantwortet am 09/12/2016 um 16:44
quelle vom benutzer

stimmen
2

Shop jede neue Eigenschaft auf jede Art von Objekt durch typecasting es ‚any‘:

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

Später können Sie es durch Gießen Ihr ausgedehntes Objekt zurück zu ‚any‘ abrufen können:

var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
Beantwortet am 25/11/2015 um 13:21
quelle vom benutzer

stimmen
2

Sie können diese Erklärung hinzufügen, die Warnungen zum Schweigen zu bringen.

declare var obj: any;

Beantwortet am 03/10/2012 um 16:02
quelle vom benutzer

stimmen
1

Ich bin überrascht, dass keine der Antworten verweisen Object.assign denn das ist die Technik, die ich verwende, wenn ich über „Komposition“ in JavaScript denken.

Und es funktioniert, wie in Typoskript erwartet:

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

Vorteile

  • geben Sicherheit über , weil Sie das nicht verwenden , müssen anyTyp überhaupt
  • Typoskript des Aggregattyp verwendet (wie durch die bezeichnet , &wenn die Art der Deklaration objectWithAllProps), die klar kommuniziert , dass wir einen neuen Typ sind Komponieren on-the-fly (dh dynamisch)

sein, die Dinge bewusst

  1. Object.assign hat seine eigene einzigartige Aspekte (die zu den erfahrensten JS Devs bekannt sind), die berücksichtigt werden sollten, wenn Typoskript zu schreiben.
    • Es kann in einer wandelbaren Art und Weise verwendet werden, oder eine unveränderliche Weise (I zeigt die unveränderliche Art und Weise oben, was bedeutet , dass existingObjectbleibt unberührt und daher keine hat emailEigenschaft. Für die meisten funktionalen Stil Programmierer, das ist eine gute Sache , da das Ergebnis die einzige neue Änderung).
    • Object.assign funktioniert am besten, wenn Sie flache Objekte. Wenn Sie zwei verschachtelte Objekte kombinieren, die Nullable-Eigenschaften enthalten, können Sie truthy Werte mit undefinierten am Ende zu überschreiben. Wenn Sie die Reihenfolge der Object.assign Argumente achten, sollten Sie in Ordnung sein.
Beantwortet am 30/01/2019 um 16:21
quelle vom benutzer

stimmen
1

Es ist möglich, ein Mitglied zu einem vorhandenen Objekt hinzufügen, indem Sie

  1. Verbreitern der Art (Lesen: ausfahren / spezialisiert die Schnittstelle)
  2. gegossen das ursprüngliche Objekt in die ausgefahrene Typ
  3. fügen Sie das Element auf das Objekt
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();
Beantwortet am 08/03/2018 um 11:20
quelle vom benutzer

stimmen
1

Wenn Sie Typoskript verwenden, vermutlich wollen Sie die Typsicherheit verwenden; wobei nackter Gegenstand und ‚alle‘ sind counterindicated.

Besser nicht verwenden Objekt oder {}, aber einige genannten Art; oder Sie können eine API mit spezifischen Typen verwenden, die Sie mit Ihrem eigenen Felder müssen erweitern. Ich habe dies auf Arbeit gefunden:

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";
Beantwortet am 02/01/2018 um 03:07
quelle vom benutzer

stimmen
1

dynamisch Eigenschaften in Maschinenschrift zu einem Objekt zugeordnet werden.

zu tun, dass Sie müssen nur so Typoskript Schnittstellen wie verwenden:

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

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

Sie können es so verwenden

var obj: IType = {};
obj['code1'] = { 
                 prop1: 'prop 1 value', 
                 prop2: 'prop 2 value' 
               };
Beantwortet am 30/03/2017 um 04:31
quelle vom benutzer

stimmen
0

Sie können diese verwenden:

this.model = Object.assign(this.model, { newProp: 0 });
Beantwortet am 09/07/2019 um 23:53
quelle vom benutzer

stimmen
0

Sie können basierend auf dem alten Objekt neues Objekt erstellen, die Ausbreitung Operator

interface MyObject {
    prop1: string;
}

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

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

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

Typoskript werden alle Felder des ursprünglichen Objekts schließen und VSCode wird die automatische Vervollständigung tun, usw.

Beantwortet am 10/06/2019 um 01:59
quelle vom benutzer

stimmen
0

Einfachste wird folgende

const obj = <any>{};
obj.prop1 = "value";
obj.prop2 = "another value"
Beantwortet am 02/05/2019 um 23:18
quelle vom benutzer

stimmen
0

Javascript:

myObj.myProperty = 1;

Typoskript:

myObj['myProperty'] = 1;
Beantwortet am 09/02/2019 um 09:43
quelle vom benutzer

stimmen
-1

Wenn Sie in der Lage sind ES6 JavaScript - Funktionen zu nutzen, können Sie Computed Eigenschaftsnamen zu handhaben sehr leicht:

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

Der [req.id] Objektschlüssel hat einen dynamischen Wert

Beantwortet am 16/01/2018 um 11:03
quelle vom benutzer

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