web-dev-qa-db-fra.com

Définition de type dans le littéral d'objet dans TypeScript

Dans les classes TypeScript, il est possible de déclarer des types pour les propriétés, par exemple:

class className {
  property: string;
};

Comment déclarer le type d'une propriété dans un littéral d'objet?

J'ai essayé le code suivant mais il ne compile pas:

var obj = {
  property: string;
};

Je reçois l'erreur suivante:

Le nom 'chaîne' n'existe pas dans la portée actuelle

Est-ce que je fais quelque chose de mal ou est-ce un bug?

267
Dace Zarina

Vous êtes assez proches, il vous suffit de remplacer le = par un :. Vous pouvez utiliser un littéral de type objet (voir section 3.5.3 du Spec) ou une interface. L'utilisation d'un littéral de type d'objet est proche de ce que vous avez:

var obj: { property: string; } = { property: "foo" };

Mais vous pouvez aussi utiliser une interface

interface MyObjLayout {
    property: string;
}

var obj: MyObjLayout = { property: "foo" };
347
Brian Terlson

Utilisez l'opérateur de conversion pour rendre ceci succinct (en convertissant null pour le type souhaité).

var obj = {
    property: <string> null
};

Un exemple plus long:

var call = {
    hasStarted: <boolean> null,
    hasFinished: <boolean> null,
    id: <number> null,
};

C'est bien mieux que d'avoir deux parties (une pour déclarer les types, la seconde pour déclarer les valeurs par défaut):

var callVerbose: {
    hasStarted: boolean;
    hasFinished: boolean;
    id: number;
} = {
    hasStarted: null,
    hasFinished: null,
    id: null,
};

Update 2016-02-10 - Gestion de la TSX (Merci @Josh)

Utilisez l'opérateur as pour TSX.

var obj = {
    property: null as string
};

Un exemple plus long:

var call = {
    hasStarted: null as boolean,
    hasFinished: null as boolean,
    id: null as number,
};

Mise à jour 2019-05-15 (modèle de code amélioré en tant qu'alternative)

Après de nombreuses années d'utilisation de const et bénéficiant d'un code plus fonctionnel, je déconseille d'utiliser ce qui précède dans la plupart des cas. (Ce qui précède crée un objet mutable dont le champ est défini dans toute la fonction au lieu de tout à la fois, ce qui entraîne des bogues avec des états incohérents).

Au lieu de cela, je recommanderais d'utiliser autant que possible les variables const, puis de composer l'objet comme étape finale:

const id = GetId();
const hasStarted = true;
...
const hasFinished = false;
...
return {hasStarted, hasFinished, id};
  • Cela va taper correctement tout sans avoir besoin de taper explicitement.
  • Il n'est pas nécessaire de retaper les noms de champs.
  • Cela conduit au code le plus propre de mon expérience.
  • Cela permet au compilateur de fournir davantage de vérifications d'état (par exemple, si vous retournez dans plusieurs emplacements, il s'assurera que le même type d'objet est toujours renvoyé - ce qui vous encourage à déclarer la valeur de retour complète à chaque position - ce qui donne un résultat parfaitement clair. intention de cette valeur).
239
Rick Love

Si vous essayez d'écrire une annotation de type, la syntaxe est la suivante:

var x: { property: string; } = ...;

Si vous essayez d'écrire un objet littéral, la syntaxe est la suivante:

var x = { property: 'hello' };

Votre code tente d'utiliser un nom de type dans une position de valeur.

14
Ryan Cavanaugh

Dans TypeScript, si nous déclarons un objet, nous utiliserons la syntaxe suivante:

[access modifier] variable name : { /* structure of object */ }

Par exemple:

private Object:{ Key1: string, Key2: number }
10
mukund patel

Je suis surpris que personne n'en parle, mais vous pouvez simplement créer une interface appelée ObjectLiteral qui accepte key: value paires de type string: any:

interface ObjectLiteral {
  [key: string]: any;
}

Ensuite, vous l'utiliseriez comme ceci:

let data: ObjectLiteral = {
  hello: "world",
  goodbye: 1,
  // ...
};

Un avantage supplémentaire est que vous pouvez réutiliser cette interface autant de fois que vous le souhaitez, sur autant d'objets que vous le souhaitez.

Bonne chance.

8
LogicalBranch

Si vous essayez d'ajouter des typages à un littéral d'objet déstructuré, par exemple dans les arguments d'une fonction, la syntaxe est la suivante:

function foo({ bar, baz }: { bar: boolean, baz: string }) {
  // ...
}

foo({ bar: true, baz: 'lorem ipsum' });
3
Egor

Dans votre code:

var obj = {
  myProp: string;
};

En fait, vous créez un littéral d'objet et assignez la chaîne de variable à la propriété myProp. Bien que ce soit une très mauvaise pratique, ce serait en fait un code TS valide (ne l'utilisez pas!):

var string = 'A string';

var obj = {
  property: string
};

Cependant, ce que vous voulez, c'est que le littéral d'objet soit typé. Ceci peut être réalisé de différentes manières:

Interface:

interface myObj {
    property: string;
}

var obj: myObj = { property: "My string" };

Type personnalisé:

type myObjType = {
    property: string
};

var obj: myObjType = { property: "My string" };

Opérateur de casting:

var obj = {
    myString: <string> 'hi',
    myNumber: <number> 132,
};

Type d'objet littéral:

var obj: { property: string; } = { property: "Mystring" };
1