Comment définir un tableau d'objets?


197

Je crée un tableau d'objets en TypeScript:

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

Quelqu'un peut-il me dire comment déclarer correctement son type? Est-il possible de faire en ligne ou aurais-je besoin de deux définitions?

Je cherche à remplacer le xxxpar une déclaration de type, afin que plus tard TypeScript m'alerte si j'utilise quelque chose comme userTestStatus[3].nammmepar erreur.

Réponses:


279

Il vaut mieux utiliser un tableau natif au lieu d'un littéral d'objet avec des propriétés de type nombre, de sorte que la numérotation (ainsi que de nombreuses autres fonctions de tableau) sont prises en charge immédiatement.

Ce que vous recherchez ici est une définition d' interface en ligne pour votre tableau qui définit chaque élément de ce tableau, qu'il soit initialement présent ou introduit plus tard:

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

Si vous initialisez immédiatement votre tableau avec des valeurs, la définition de type explicite n'est pas une nécessité; TypeScript peut automatiquement déduire la plupart des types d'éléments à partir de l'affectation initiale:

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

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

4
Vous pouvez également déclarer un tableau d'objets de cette façon:let someArray: Array<{ id: number, name: string }> = []
— Alexander Kim

74

Ce que vous avez ci-dessus est un objet, pas un tableau.

Pour faire un tableau, utilisez [& ]pour entourer vos objets.

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

En plus de cela, TypeScript est un sur-ensemble de JavaScript, donc tout ce qui est valide JavaScript sera TypeScript valide, donc aucune autre modification n'est nécessaire.

Clarification des commentaires de l'OP ... besoin d'une définition pour le modèle affiché

Vous pouvez utiliser les types définis ici pour représenter votre modèle d'objet:

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

Désolé, ma question n'était peut-être pas claire. Ce que je voulais faire était de trouver une définition pour userTestStatus.

1
@Marilou Vous pouvez généralement obtenir la définition simplement en survolant la userTestStatusvariable dans votre IDE préféré ... le terrain de jeu TypeScript montre { id: number, name: string; }[]. Vous pouvez envelopper cela dans une interface si vous le souhaitez interface NameThis { id: number, name: string; }et NameThis[]comme type de tableau.
— Fenton

J'ai essayé mais cela me donne quelques erreurs. Cependant, je pense que c'est quelque chose comme je veux: userTestStatus: {id: nombre, nom: chaîne; } [] = {"0": {"id": 0, "nom": "Disponible"}, "1": {"id": 1, "nom": "Prêt"},

Dans votre exemple de définition var arr: MyType, vous n'utiliseriez pas les déclarations de nom / index de propriété telles que "0": { … }; vous utiliseriez simplement l'objet littéral à ce stade.
— gfullam

@gfullam vous avez raison, j'ai mis à jour ma réponse (c'était une modification rapide et imprudente)
— Brocco

34

Certaines tslintrègles désactivent l'utilisation de [], exemple de message:Array type using 'T[]' is forbidden for non-simple types. Use 'Array<T>' instead.

Ensuite, vous l'écririez comme:

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

2
Approche la plus pratique jamais réalisée. c'est une solution simple et directe pour les cas d'utilisation de tableaux simples. Prenez mon +1
— Julio Vedovatto

16

Ce que vous voulez vraiment peut être simplement une énumération

Si vous recherchez quelque chose qui se comporte comme une énumération (parce que je vois que vous définissez un objet et attachez un ID séquentiel 0, 1, 2 et contient un champ de nom que vous ne voulez pas mal orthographier (par exemple, nom vs naaame) , il vaut mieux définir une énumération car l'ID séquentiel est pris en charge automatiquement et vous fournit une vérification de type dès la sortie de la boîte.

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

Les valeurs ci-dessus seront automatiquement mappées, par exemple "0" pour "Disponible", et vous pouvez y accéder en utilisant TestStatus.Available. Et Typescript appliquera le type lorsque vous les passerez.

Si vous insistez pour définir un nouveau type en tant que tableau de votre type personnalisé

Vous vouliez un tableau d'objets (pas exactement un objet avec les clés "0", "1" et "2"), définissons donc le type de l'objet, d'abord, puis un type de tableau contenant.

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

Désolé, ma question n'était peut-être pas claire. Ce que je voulais faire était de trouver une définition pour userTestStatus afin que Typescript me permette de vérifier où il est utilisé et ainsi, par exemple, je ne pouvais pas entrer userTestStatus [1] .naaaame.

Je voulais trouver quelque chose à mettre entre le "userTestStatus" et le "=". De la même manière que je pourrais y mettre une chaîne ou un nombre pour indiquer le type de la variable. Quelque chose comme Brocco vient de le faire, mais avec une seule ligne si cela est possible.

-1

Vous pouvez aussi essayer

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

Pour vérifier le fonctionnement de l'enregistrement: https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt

Ici, dans notre cas, Record est utilisé pour déclarer un objet dont la clé sera une chaîne et dont la valeur sera de type IData alors maintenant il nous fournira Intellisense lorsque nous essaierons d'accéder à sa propriété et lèvera une erreur de type au cas où nous essaierions quelque chose comme userTestStatus [0] .nameee


vous devriez donner plus d'informations sur les raisons pour lesquelles cela résout le problème
— Cornel Raiu
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.