J'ai actuellement à la fois un tableau de chaînes et un type d'union littéral de chaîne contenant les mêmes chaînes:
const furniture = ['chair', 'table', 'lamp'];
type Furniture = 'chair' | 'table' | 'lamp';
J'ai besoin des deux dans ma candidature, mais j'essaie de garder mon code SEC. Existe-t-il un moyen de déduire l'un de l'autre?
Je veux essentiellement dire quelque chose comme type Furniture = [any string in furniture array]
, il n'y a donc pas de chaînes en double.
Avec l'utilisation de paramètres de repos génériques, il existe un moyen de déduire correctement string[]
comme type de Tuple littéral, puis obtenez le type d'union des littéraux.
Ça va comme ça:
const Tuple = <T extends string[]>(...args: T) => args;
const furniture = Tuple('chair', 'table', 'lamp');
type Furniture = typeof furniture[number];
En savoir plus sur les paramètres de repos génériques
TypeScript version 3.4 a introduit les soi-disant contextes const , qui sont un moyen de déclarer un type Tuple immuable et d'obtenir directement le type littéral étroit (sans le besoin d'appeler une fonction comme indiqué ci-dessus).
Avec cette nouvelle syntaxe, nous obtenons cette belle solution concise:
const furniture = ['chair', 'table', 'lamp'] as const;
type Furniture = typeof furniture[number];
Plus d'informations sur les nouveaux contextes const se trouvent dans ce PR ainsi que dans les notes de version .
La meilleure solution de contournement disponible:
const furnitureObj = { chair: 1, table: 1, lamp: 1 };
type Furniture = keyof typeof furnitureObj;
const furniture = Object.keys(furnitureObj) as Furniture[];
Idéalement, nous pourrions le faire:
const furniture = ['chair', 'table', 'lamp'];
type Furniture = typeof furniture[number];
Malheureusement, aujourd'hui furniture
est déduit comme string[]
, ce qui signifie que Furniture
est désormais également un string
.
Nous pouvons appliquer le typage comme un littéral avec une annotation manuelle, mais cela ramène la duplication:
const furniture = ["chair", "table", "lamp"] as ["chair", "table", "lamp"];
type Furniture = typeof furniture[number];
TypeScript problème # 10195 suit la possibilité d'indiquer à TypeScript que la liste doit être déduite comme un tuple statique et non string[]
, alors ce sera peut-être possible à l'avenir.