832 Stimmen

Wie weise ich einem Objekt in TypeScript dynamisch Eigenschaften zu?

Wenn ich einem Objekt in Javascript programmatisch eine Eigenschaft zuweisen wollte, würde ich es so machen:

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

In TypeScript erzeugt dies jedoch einen Fehler:

Die Eigenschaft 'prop' existiert nicht bei einem Wert vom Typ '{}'.

Wie soll ich einem Objekt in TypeScript eine neue Eigenschaft zuweisen?

0voto

Rafał Cieślak Punkte 938

Ich bin auf dieses Problem gestoßen, als ich versucht habe, ein Objekt teilweise zu aktualisieren, das als Speicher für den Zustand fungiert hat.

type State = {
  foo: string;
  bar: string;
  baz: string;
};

const newState = { foo: 'abc' };

if (someCondition) {
  newState.bar = 'xyz'
}

setState(newState);

In diesem Szenario wäre die beste Lösung die Verwendung von Partial<T> . Es macht alle Eigenschaften des angegebenen Typs optional, indem es die ? Zeichen. Lesen Sie mehr darüber in ein spezifischeres SO-Thema darüber, alle Eigenschaften eines Typs optional zu machen .

Ich habe das Problem folgendermaßen gelöst Partial<T> :

type State = {
  foo: string;
  bar: string;
  baz: string;
};

const newState: Partial<State> = { foo: 'abc' };

if (someCondition) {
  newState.bar = 'xyz';
}

setState(newState);

Dies ist ähnlich wie das, was fregante in ihrer Antwort beschrieben, aber ich wollte ein klareres Bild für diesen speziellen Anwendungsfall (die häufig in Frontend-Anwendungen ist) zu malen.

0voto

ES6 verwenden Map wenn eine Karte wirklich beliebige Werte festen Typs annehmen kann, und ansonsten optionale Eigenschaften

Ich denke, das ist die Richtschnur, an die ich mich halten werde. ES6 Karte kann in Typescript wie erwähnt getan werden: ES6 Karte in Typescript

Der Hauptanwendungsfall für optionale Eigenschaften sind "Options"-Parameter von Funktionen: Verwendung benannter Parameter JavaScript (auf der Grundlage von Typescript) In diesem Fall kennen wir im Voraus die genaue Liste der erlaubten Eigenschaften, also ist es am vernünftigsten, einfach eine explizite Schnittstelle zu definieren und alles, was optional ist, mit ? wie erwähnt bei: https://stackoverflow.com/a/18444150/895245 um so viel Typüberprüfung wie möglich zu erhalten:

const assert = require('assert')

interface myfuncOpts {
  myInt: number,
  myString?: string,
}

function myfunc({
  myInt,
  myString,
}: myfuncOpts) {
  return `${myInt} ${myString}`
}

const opts: myfuncOpts = { myInt: 1 }
if (process.argv.length > 2) {
  opts.myString = 'abc'
}

assert.strictEqual(
  myfunc(opts),
  '1 abc'
)

Und dann verwende ich Map, wenn es sich um etwas wirklich Beliebiges (unendlich viele mögliche Schlüssel) und einen festen Typ handelt, z. B.:

const assert = require('assert')
const integerNames = new Map<number, string>([[1, 'one']])
integerNames.set(2, 'two')
assert.strictEqual(integerNames.get(1), 'one')
assert.strictEqual(integerNames.get(2), 'two')

Getestet am:

  "dependencies": {
    "@types/node": "^16.11.13",
    "typescript": "^4.5.4"
  }

-1voto

Tung Nguyen Punkte 7

Versuchen Sie dies:

export interface QueryParams {
    page?: number,
    limit?: number,
    name?: string,
    sort?: string,
    direction?: string
}

Dann verwenden Sie es

const query = {
    name: 'abc'
}
query.page = 1

-1voto

joshuapoehls Punkte 27785

Sie können diese Erklärung hinzufügen, um die Warnungen auszuschalten.

declare var obj: any;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X