Typescript string literal-unietype
Ik heb een klasse-eigenschap met een type dat de unie is van meerdere string-literals:
public reaction? : 'haha' | 'wow' | 'angry' | 'sad' | 'like';
Wat ik probeerde te doen, was deze strings ergens anders in een soort array te definiëren en vervolgens gewoon de array in de eigenschapsdefinitie te gebruiken. Dus zoiets als:
allowedStrings = ['haha','wow','angry','sad','like'];
public reaction? : allowedStrings;
Ik begrijp dat het bovenstaande niet mogelijk is, maar het is het algemene idee. Biedt TypeScript iets dat het werk doet?
Antwoord #1
Sinds TypeScript 3.4 kunt u een type genereren van een runtime-waarde met behulp van const-asserties.
const allowedStrings = ['haha', 'wow', 'angry', 'sad', 'like'] as const;
type AllowedString = typeof allowedStrings[number]; // [number] is important here
// We can freely map over values
const mapped = allowedStrings.map((s) => s.toUpperCase());
// And use generated type to create type-safe functions
const process = (s: AllowedString) => {
// Type of s is
// s: "haha" | "wow" | "angry" | "sad" | "like"
return s;
};
Antwoord #2
Het hangt precies af van hoe je het van plan bent te gebruiken, maar een string enum kan je geven wat je zoekt:
enum ReactionKind {
haha = 'haha',
wow = 'wow',
angry = 'angry',
sad = 'sad',
like = 'like'
}
const reaction: ReactionKind = ReactionKind.angry;
// Get the string value
const stringValue = ReactionKind[reaction];
// Get the Enum from a string
const enumValue = ReactionKind['wow'];
Je kunt nog steeds de gewone tekenreekswaarden gebruiken waar je ze nodig hebt, maar je kunt ze gebruiken als een type en als een runtime-waarde, wat lijkt te zijn waar je naar op zoek bent.
Je zult ook merken dat bij string-enums, als je een string sleutel gebruikt bij het koppelen aan een enum, dit gecontroleerd wordt... zolang je --noImplicitAny gebruikt.
// Error
const enumValue = ReactionKind['wat'];
