Wie kann ich ein Array von Objekten definieren?


197

Ich erstelle ein Array von Objekten in TypeScript:

 userTestStatus xxxx = {
    "0": { "id": 0, "name": "Available" },
    "1": { "id": 1, "name": "Ready" },
    "2": { "id": 2, "name": "Started" }
 };

Kann mir jemand sagen, wie ich seinen Typ richtig deklarieren kann? Ist es möglich, Inline zu machen oder brauche ich zwei Definitionen?

Ich xxxmöchte das durch eine Typdeklaration ersetzen , damit TypeScript mich später benachrichtigt, wenn ich versehentlich etwas verwendet habe userTestStatus[3].nammme.

Antworten:


279

Sie sind besser dran, ein natives Array zu verwenden anstelle eines Objektliteral mit nummerähnlichen Eigenschaften zu verwenden, damit die Nummerierung (sowie zahlreiche andere Array-Funktionen) von der Stange übernommen wird.

Was Sie hier suchen, ist eine Inline- Schnittstellendefinition für Ihr Array, die jedes Element in diesem Array definiert, unabhängig davon, ob es ursprünglich vorhanden ist oder später eingeführt wird:

let userTestStatus: { id: number, name: string }[] = [
    { "id": 0, "name": "Available" },
    { "id": 1, "name": "Ready" },
    { "id": 2, "name": "Started" }
];

userTestStatus[34978].nammme; // Error: Property 'nammme' does not exist on type [...]

Wenn Sie Ihr Array sofort mit Werten initialisieren, ist die explizite Typdefinition nicht erforderlich. TypeScript kann die meisten Elementtypen automatisch aus der anfänglichen Zuweisung ableiten:

let userTestStatus = [
    { "id": 0, "name": "Available" },
    ...
];

userTestStatus[34978].nammme; // Error: Property 'nammme' does not exist on type [...]

4
Sie können auch eine Reihe von Objekten folgendermaßen deklarieren:let someArray: Array<{ id: number, name: string }> = []
Alexander Kim

74

Was Sie oben haben, ist ein Objekt, kein Array.

Um ein Array zu erstellen, verwenden Sie [& ], um Ihre Objekte zu umgeben.

userTestStatus = [
  { "id": 0, "name": "Available" },
  { "id": 1, "name": "Ready" },
  { "id": 2, "name": "Started" }
];

Abgesehen davon ist TypeScript eine Obermenge von JavaScript. Was auch immer gültiges JavaScript ist, ist gültiges TypeScript, sodass keine weiteren Änderungen erforderlich sind.

Feedback-Klärung von OP ... benötigt eine Definition für das veröffentlichte Modell

Sie können die hier definierten Typen verwenden, um Ihr Objektmodell darzustellen:

type MyType = {
    id: number;
    name: string;
}

type MyGroupType = {
    [key:string]: MyType;
}

var obj: MyGroupType = {
    "0": { "id": 0, "name": "Available" },
    "1": { "id": 1, "name": "Ready" },
    "2": { "id": 2, "name": "Started" }
};
// or if you make it an array
var arr: MyType[] = [
    { "id": 0, "name": "Available" },
    { "id": 1, "name": "Ready" },
    { "id": 2, "name": "Started" }
];

Entschuldigung, vielleicht war meine Frage nicht klar. Ich wollte eine Definition für userTestStatus finden.

1
@Marilou Normalerweise können Sie die Definition einfach erhalten, indem Sie den Mauszeiger über die userTestStatusVariable in Ihrer Lieblings-IDE bewegen ... der TypeScript-Spielplatz zeigt dies { id: number, name: string; }[]. Sie können dies in eine Schnittstelle einbinden, wenn Sie möchten interface NameThis { id: number, name: string; }und NameThis[]als Array-Typ.
Fenton

Ich habe es versucht, aber es gibt mir ein paar Fehler. Ich denke jedoch, dass es so etwas wie ich will: userTestStatus: {id: number, name: string; } [] = {"0": {"id": 0, "name": "Available"}, "1": {"id": 1, "name": "Ready"},

In Ihrer Beispieldefinition var arr: MyTypewürden Sie die Eigenschaftsnamen- / Indexdeklarationen nicht verwenden, z "0": { … }. Sie würden an dieser Stelle nur das Objektliteral verwenden.
Gfullam

@gfullam Sie sind richtig, ich habe meine Antwort aktualisiert (es war eine schnelle unachtsame Bearbeitung)
Brocco

34

Einige tslintRegeln deaktivieren die Verwendung von [], Beispielnachricht:Array type using 'T[]' is forbidden for non-simple types. Use 'Array<T>' instead.

Dann würden Sie es schreiben wie:

var userTestStatus: Array<{ id: number, name: string }> = Array(
    { "id": 0, "name": "Available" },
    { "id": 1, "name": "Ready" },
    { "id": 2, "name": "Started" }
);

2
Der praktischste Ansatz aller Zeiten. Es ist eine einfache und direkte Lösung für einfache Array-Anwendungsfälle. Nimm meine +1
Julio Vedovatto

16

Was Sie wirklich wollen, kann einfach eine Aufzählung sein

Wenn Sie nach etwas suchen, das sich wie eine Aufzählung verhält (weil ich sehe, dass Sie ein Objekt definieren und eine sequentielle ID 0, 1, 2 anhängen und ein Namensfeld enthalten, das Sie nicht falsch schreiben möchten (z. B. name vs naaame) Definieren Sie besser eine Aufzählung, da die sequentielle ID automatisch verwaltet wird und Sie sofort eine Typüberprüfung erhalten.

enum TestStatus {
    Available,     // 0
    Ready,         // 1
    Started,       // 2
}

class Test {
    status: TestStatus
}

var test = new Test();
test.status = TestStatus.Available; // type and spelling is checked for you,
                                    // and the sequence ID is automatic

Die obigen Werte werden automatisch zugeordnet, z. B. "0" für "Verfügbar", und Sie können mit darauf zugreifen TestStatus.Available. Und Typescript erzwingt den Typ, wenn Sie diese weitergeben.

Wenn Sie darauf bestehen, einen neuen Typ als Array Ihres benutzerdefinierten Typs zu definieren

Sie wollten ein Array von Objekten (nicht genau ein Objekt mit den Schlüsseln "0", "1" und "2"). Definieren Sie also zuerst den Typ des Objekts und dann den Typ eines enthaltenen Arrays.

class TestStatus {
    id: number
    name: string

    constructor(id, name){
        this.id = id;
        this.name = name;
    }
}

type Statuses = Array<TestStatus>;

var statuses: Statuses = [
    new TestStatus(0, "Available"),
    new TestStatus(1, "Ready"),
    new TestStatus(2, "Started")
]

Entschuldigung, vielleicht war meine Frage nicht klar. Was ich tun wollte, war, eine Definition für userTestStatus zu finden, damit ich mit Typescript überprüfen kann, wo es verwendet wird, und so konnte ich beispielsweise userTestStatus [1] .naaaame nicht eingeben.

Ich wollte etwas finden, das zwischen "userTestStatus" und "=" eingefügt werden kann. Genauso wie ich dort eine Zeichenfolge oder eine Zahl einfügen könnte, um zu sagen, welchen Typ die Variable hat. So etwas wie Brocco hat es gerade getan, aber mit nur einer Zeile, wenn das möglich ist.

-1

Sie können es auch versuchen

    interface IData{
        id: number;
        name:string;
    }

    let userTestStatus:Record<string,IData> = {
        "0": { "id": 0, "name": "Available" },
        "1": { "id": 1, "name": "Ready" },
        "2": { "id": 2, "name": "Started" }
    };

So überprüfen Sie, wie die Aufzeichnung funktioniert: https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt

In unserem Fall wird Record verwendet, um ein Objekt zu deklarieren, dessen Schlüssel eine Zeichenfolge ist und dessen Wert vom Typ IData ist. Jetzt liefert es uns Intellisense, wenn wir versuchen, auf seine Eigenschaft zuzugreifen, und gibt einen Typfehler aus, falls wir es versuchen so etwas wie userTestStatus [0] .nameee


Sie sollten mehr Informationen darüber geben, warum dies das
vorliegende
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.