126 votes

"Envisagez d'utiliser un type d'objet mappé à la place." - Qu'est-ce qu'un type d'objet mappé et comment l'utiliser ici ?

interface Foo { 
    [foo: "hello" | "world"]: string;
}

Je reçois un message d'erreur comme

An index signature parameter type cannot be a union type. Consider using a mapped object type instead.

Qu'est-ce qu'un type d'objet mappé, et comment l'utiliser ?

158voto

Daniel Rosenwasser Points 7171

Un type d'objet mappé opère sur un ensemble de types singletons et produit un nouveau type d'objet où chacun de ces singletons est transformé en un nom de propriété.

Par exemple, ceci :

type Foo = {
    [K in "hello" | "world"]: string
};

serait équivalent à

type Foo = {
    "hello": string;
    "world": string;
};

Gardez à l'esprit qu'un type d'objet mappé est un opérateur de type distinct - la syntaxe entre accolades ne peut pas être utilisée dans les interfaces, ou les types d'objets avec d'autres membres. Par exemple

interface Foo {
    [K in "hello" | "world"]: string
}

produit l'erreur suivante :

A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.

Les types d'objets mappés sont utiles pour un grand nombre de choses différentes. Plus d'informations ici : http://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types

13 votes

Existe-t-il une version de ceci où le type ne peut avoir qu'une seule propriété dont le nom doit être soit hello o world ?

1 votes

C'est aussi ce que j'essaie de comprendre : comment faire un type qui a soit hello o world prop et être capable d'affiner la saisie pour utiliser le bon type...

5 votes

Je tiens à souligner la différence. Pour créer un type mappé, nous remplaçons l'élément " :" con " dans " . Et devient [foo in "hello" | "world"]

5voto

ChrisKader Points 61

C'est invalide :

    type DirectiveType = 'package-as' | 'externals' | 'move-folders' | 'ignore';
    type Directives = { [key:DirectiveType]?: RootDirectives };

    export class PkgmetaFile {
        private _directives: Directives = {};
    }

Mais c'est valable :

    type DirectiveType = 'package-as' | 'externals' | 'move-folders' | 'ignore';
    type Directives = { [Key in DirectiveType as string]?: RootDirectives };

    export class PkgmetaFile {
        private _directives: Directives = {};
    }

0 votes

Pourriez-vous donner plus de détails sur votre réponse ? Essayer de comprendre une réponse sans explication peut conduire à des malentendus.

2 votes

J'ai pu déduire une clé d'un objet mappé à partir d'un type d'union en utilisant simplement "as string" à la fin de "DirectiveType

0 votes

C'est la meilleure réponse car elle préserve la possibilité de spécifier un type de clé et de faire en sorte que plusieurs interfaces utilisent ce type de clé. La réponse acceptée est plus limitée dans son champ d'application et presque inutile pour mes besoins.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X