introspektion på anpassad TypeScript-typ
Jag definierar en anpassad typ i TypeScript
type MyType = 'left' | 'right';
Hur kan jag kontrollera om en variabel matchar denna typ? Hur kan jag iterera över de möjliga värdena för denna typ? (för att till exempel skapa ett motsvarande selekteringselement)
Svar #1
Att lägga till typinformation vid körning är ett uttalat icke-mål för TypeScript. Det betyder att de inte vill tillåta att du definierar en typ och sedan undersöker den vid körning.
Däremot fungerar det precis lika bra åt andra hållet: skapa ett objekt som existerar vid körning, och använd TypeScript för att härleda typinformation om det. Här är ett sätt att göra det i ditt fall.
Först, lägg till följande hjälpfunktion:
function stringLiteralArray<T extends string>(...args: T[]): T[] {
return args;
}
Detta hjälper TypeScript att härleda en matris av strängliteraler istället för bara string[].
Nu kan du skapa ett runtime-objekt som heter myType och härleda MyType från det:
const myType = stringLiteralArray('left', 'right'); // ('left'|'right')[]
type MyType = (typeof myType)[number]; // 'left' | 'right'
Då har du både information om typ vid körning och kompilering. Du kan kontrollera om en variabel är av den typen med följande användardefinierade typvakt:
function isMyType(x: any): x is MyType {
return myType.includes(x); // needs es2016 at least, or implement yourself
}
Du kan iterera myType vid körning, och du kan göra fullständighetskontroll på MyType vid kompileringstid:
function foo(x: MyType): string { // error, not exhaustive
switch (x) {
case 'left': return 'L';
case 'rihgt': return 'R'; // error, 'rihgt' isn't 'left'|'right'
}
}
Hoppas det hjälper.
Svar #2
Du kan inte göra det med en "enkel typ", men sedan Typescript 2.4 kan du använda enums med strängvärden:
enum MyType {
LEFT='left',
RIGHT='right'
}
for (let i in MyType) {
console.log(MyType[i]); //will print "left" and "right"
}
Det fungerar eftersom under körning finns ett objekt som heter MyType och dess värde är {RIGHT:'right',LEFT:'left'}.
