Typescript-typen string kan inte tilldelas typen keyof
Jag har följande kod:
const KeyboardEventKeys = {
Escape: 'Escape',
Enter: 'Enter',
Tab: 'Tab'
};
type KeyboardEventKeys = keyof (typeof KeyboardEventKeys);
function doSomething(key: KeyboardEventKeys) {}
När jag skickar värdet på en av objektets egenskaper till en funktion skriker den åt mig:
doSomething(KeyboardEventKeys.Enter);
En lösning är att casta as KeyboardEventKeys, men det är en överflödig lösning. Hur kan jag göra det utan det?
Jag vill inte heller lägga till doSomething(key: KeyboardEventKeys | string) eftersom jag kommer att förlora typkontrollen.
Svar #1
Sedan TypeScript 3.4 kan du tvinga kompilatorn att bevara literaltyper genom att använda den speciella as const-kastkonstruktionen. Så här kan du skriva
const KeyboardEventKeys = {
Escape: 'Escape',
Enter: 'Enter',
Tab: 'Tab'
} as const;
type KeyboardEventKeys = keyof typeof KeyboardEventKeys;
function doSomething(key: KeyboardEventKeys) {}
Men i slutändan rekommenderar jag att använda [const] enum KeyboardEventKeys { ... } istället.
Svar #2
Lösningen att använda ett enum är en bra idé, och jag skulle rekommendera att du använder det.
Anledningen till att du får ett fel är att TypeScript inte kommer att härleda strängliteraltyper för const-medlemmar. Du kan tvinga kompilatorn att härleda strängliteraltyper genom att använda en extra funktion när du skapar const:
function createEnum<T extends { [P in keyof T]: P }>(o: T) {
return o
}
const KeyboardEventKeys = createEnum({ // typed as { Escape: "Escape"; Enter: "Enter"; Tab: "Tab"; }
Escape: 'Escape',
Enter: 'Enter',
Tab: 'Tab'
});
type KeyboardEventKeys = keyof (typeof KeyboardEventKeys);
function doSomething(key: KeyboardEventKeys) { }
doSomething("Enter")
doSomething("") //err
