web-dev-qa-db-fra.com

Un type de paramètre de signature d'index ne peut pas être un type d'union. Pensez à utiliser un type d'objet mappé à la place

J'essaie d'utiliser le modèle suivant:

enum Option {
  ONE = 'one',
  TWO = 'two',
  THREE = 'three'
}

interface OptionRequirement {
  someBool: boolean;
  someString: string;
}

interface OptionRequirements {
  [key: Option]: OptionRequirement;
}

Cela me semble très simple, mais j'obtiens l'erreur suivante:

Un type de paramètre de signature d'index ne peut pas être un type d'union. Envisagez plutôt d'utiliser un type d'objet mappé.

Qu'est-ce que je fais mal?

46
john maccarthy

Vous pouvez utiliser l'opérateur TS "in" et procédez comme suit:

enum Options {
  ONE = 'one',
  TWO = 'two',
  THREE = 'three',
}
interface OptionRequirement {
  someBool: boolean;
  someString: string;
}
interface OptionRequirements {
  [key in Options]: OptionRequirement; // Note that "key in".
}
63

La solution la plus simple consiste à utiliser Record

type OptionRequirements = Record<Options, OptionRequirement>

Vous pouvez également l'implémenter vous-même comme:

type OptionRequirements = {
  [key in Options]: OptionRequirement;
}

Cette construction n'est disponible que pour type, mais pas interface.

Le problème dans votre définition est que la clé de votre interface doit être de type Options, où Options est une énumération, pas une chaîne, un nombre ou un symbole.

Le key in Options signifie "pour ces clés spécifiques qui sont dans le type d'union Options".

type alias est plus flexible et puissant que interface.

Si votre type n'a pas besoin d'être utilisé en classe, choisissez type sur interface.

28
unional

Vous ne pouvez pas utiliser un enum comme clé.

Consultez cette réponse si vous souhaitez vraiment une solution: https://github.com/Microsoft/TypeScript/issues/2491#issuecomment-260864535

0
Hugo Laplace

J'ai eu un problème similaire, mais mon cas était avec une autre propriété de champ dans l'interface, donc ma solution comme exemple avec facultatif propriété de champ avec une énumération pour les clés:

export enum ACTION_INSTANCE_KEY {
  cat = 'cat',
  dog = 'dog',
  cow = 'cow',
  book = 'book'
}

type ActionInstances = {
  [key in ACTION_INSTANCE_KEY]?: number; // cat id/dog id/cow id/ etc // <== optional
};

export interface EventAnalyticsAction extends ActionInstances { // <== need to be extended
  marker: EVENT_ANALYTIC_ACTION_TYPE; // <== if you wanna add another field to interface
}
0
Kurkov Igor