Come posso definire una matrice di oggetti?


200

Sto creando una matrice di oggetti in TypeScript:

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

Qualcuno può dirmi come potrei dichiarare correttamente il suo tipo? È possibile fare in linea o avrei bisogno di due definizioni?

Sto cercando di sostituire la xxxcon una dichiarazione di tipo, in modo che in seguito TypeScript mi ​​avviserebbe se avessi usato qualcosa di simile userTestStatus[3].nammmeper errore.

Risposte:


285

È meglio usare un array nativo invece di un oggetto letterale con proprietà simili a un numero, in modo che la numerazione (così come numerose altre funzioni dell'array) si occupino del pronto intervento.

Quello che stai cercando qui è una definizione di interfaccia inline per il tuo array che definisce tutti gli elementi di tale array, sia inizialmente presenti che introdotti in seguito:

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 [...]

Se si sta inizializzando immediatamente l'array con valori, la definizione esplicita del tipo non è necessaria; TypeScript può inferire automaticamente la maggior parte dei tipi di elementi dall'assegnazione iniziale:

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

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

4
Inoltre puoi dichiarare una serie di oggetti in questo modo:let someArray: Array<{ id: number, name: string }> = []
Alexander Kim,

77

Quello che hai sopra è un oggetto, non un array.

Per creare un array, usa [e ]per circondare i tuoi oggetti.

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

A parte questo, TypeScript è un superset di JavaScript, quindi qualunque cosa sia JavaScript valido sarà TypeScript valido, quindi non sono necessarie altre modifiche.

Chiarimento di feedback dall'OP ... necessita di una definizione per il modello pubblicato

È possibile utilizzare i tipi definiti qui per rappresentare il modello a oggetti:

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" }
];

Scusa forse la mia domanda non era chiara. Quello che volevo fare era trovare una definizione per userTestStatus.

1
@Marilou Di solito puoi ottenere la definizione semplicemente passando con il mouse sopra la userTestStatusvariabile nel tuo IDE preferito ... mostra il parco giochi TypeScript { id: number, name: string; }[]. Se lo desideri, puoi avvolgerlo in un'interfaccia interface NameThis { id: number, name: string; }e NameThis[]come tipo di array.
Fenton,

Ho provato questo, ma mi dà alcuni errori. Comunque penso che sia qualcosa come voglio: userTestStatus: {id: number, name: string; } [] = {"0": {"id": 0, "name": "Available"}, "1": {"id": 1, "name": "Ready"},

Nel tuo esempio di definizione var arr: MyType, non useresti il ​​nome della proprietà / dichiarazioni di indice come "0": { … }; a questo punto useresti semplicemente l'oggetto letterale.
gfullam,

@gfullam hai ragione, ho aggiornato la mia risposta (è stata una rapida modifica incurante)
Brocco

36

Alcune tslintregole disabilitano l'uso di [], messaggio di esempio:Array type using 'T[]' is forbidden for non-simple types. Use 'Array<T>' instead.

Quindi lo scriveresti come:

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

2
L'approccio più pratico di sempre. è una soluzione semplice e diretta per semplici casi d'uso dell'array. Prendi il mio +1
Julio Vedovatto il

18

Quello che vuoi davvero potrebbe essere semplicemente un elenco

Se stai cercando qualcosa che si comporta come un'enumerazione (perché vedo che stai definendo un oggetto e allegando un ID sequenziale 0, 1, 2 e contiene un campo del nome che non vuoi sbagliare (per esempio nome vs naaame) , è meglio definire un'enumerazione perché l'ID sequenziale viene gestito automaticamente e ti fornisce la verifica del tipo pronta per l'uso.

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

I valori sopra saranno automaticamente mappati, ad es. "0" per "Disponibile", e puoi accedervi usando TestStatus.Available. E Typescript imporrà il tipo quando passi quelli in giro.

Se insisti nel definire un nuovo tipo come matrice del tuo tipo personalizzato

Volevi una matrice di oggetti (non esattamente un oggetto con le chiavi "0", "1" e "2"), quindi definiamo prima il tipo di oggetto, quindi un tipo di matrice contenente.

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")
]

Scusa forse la mia domanda non era chiara. Quello che volevo fare era trovare una definizione per userTestStatus in modo che Typescript mi ​​permettesse di controllare dove veniva utilizzato e, ad esempio, non potevo inserire userTestStatus [1] .naaaame.

Volevo trovare qualcosa da mettere tra "userTestStatus" e "=". Allo stesso modo in cui potrei inserire la stringa o il numero per dire che tipo ha la variabile. Qualcosa come Brocco ha appena fatto, ma con una sola riga, se possibile.

-1

Puoi anche provare

    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" }
    };

Per verificare come funziona il record: https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt

Qui nel nostro caso Record viene utilizzato per dichiarare un oggetto la cui chiave sarà una stringa e il cui valore sarà di tipo IData, quindi ora ci fornirà intellisense quando proveremo ad accedere alla sua proprietà e genereremo un errore di tipo nel caso in cui proveremo qualcosa come userTestStatus [0] .nameee


dovresti dare maggiori informazioni sul perché questo risolva il problema a portata di mano
Cornel Raiu,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.