web-dev-qa-db-fra.com

Comment parcourir un type littéral personnalisé en tapuscrit?

J'ai défini un type littéral personnalisé dans TypeScript:

export type Market = 'au'|'br'|'de';

Maintenant, je veux parcourir chaque Market possible sans avoir à créer un tableau de Market[] en premier lieu car il se sent redondant et je peux oublier d'ajouter une option:

const markets: Market[] = ['au', 'br', 'de'];
markets.forEach((market: Market) => {
    console.log(market);
});

Existe-t-il un moyen d'y parvenir avec dactylographie?

18
k0pernikus

Non, vous ne pouvez pas le faire, car des informations de type pur comme celles-ci n'existent pas au moment de l'exécution.

Il est hypothétiquement plausible de procéder dans l'autre sens (définir une liste normale de chaînes, puis dériver le 'au'|'br'|'de' type à partir de cela), mais je ne pense pas que le compilateur TypeScript (2.0 ou 2.1) en déduise actuellement pour vous - pour autant que je sache, le type de marchés sera toujours string[] normalement.

La bonne réponse à cela est d'utiliser des énumérations. Ils définissent un type avec chacune de leurs valeurs, et il est possible d'obtenir une liste de toutes leurs valeurs de chaîne: Comment énumérer par programme un type d'énumération dans TypeScript 0.9.5? .

Le seul inconvénient des énumérations est que leur représentation d'exécution est différente (sous le capot, il s'agit en fait de nombres, pas de chaînes). Cependant, votre code peut toujours les traiter comme des valeurs lisibles de Nice, il vous suffit de les traduire en chaînes si vous en avez besoin en tant que noms de chaînes lors de l'exécution. C'est aussi simple que cela: donné une énumération MarketEnum et une valeur myEnumValue, MarketEnum[myEnumValue] est le nom de la valeur sous forme de chaîne).

8
Tim Perry

Voici une manière alternative:

enum Market {
   'eu' = 'eu',
   'us' = 'us',
}

const all_possible_market_values = getStringValuesFromEnum(Market)

function getStringValuesFromEnum<T>(myEnum: T): (keyof T)[] {
   return Object.keys(myEnum) as any
}

La représentation sous-jacente n'est plus des nombres, c'est la chaîne.

"use strict";
var Market;

(function (Market) {
    Market["eu"] = "eu";
    Market["us"] = "us";
})(Market || (Market = {}));

const all_possible_market_values = getStringValuesFromEnum(Market);

function getStringValuesFromEnum(myEnum) {
    return Object.keys(myEnum);
}
1
Joseph Andaverde

Voici ce que je ferais pour créer un tableau qui contient toutes vos valeurs au moment de l'exécution et qui est vérifié au moment de la compilation:

export type Market = 'eu' | 'us'

export const MARKET_TYPES: Market[] = (() => {
   const markets: Market[] = ['eu', 'us']

   return markets.map((x: Market) => {
      if (x === 'eu') {
         return x
      } else if (x === 'us') {
         return x
      } else {
         const _exhaustive_check: never = x
         return _exhaustive_check
      }
   })
})()
1
Joseph Andaverde