Explain to me what keyof typeof
means in TypeScript
Example:
enum ColorsEnum {
white = '#ffffff',
black = '#000000',
}
type Colors = keyof typeof ColorsEnum;
The last row is equivalent to:
type Colors = "white" | "black"
But how does it work?
I would expect typeof ColorsEnum
to return something like "Object"
and then keyof "Object"
to not do anything interesting. But I am obviously wrong.
keyof
takes an object type and returns a type that accepts any of the object's keys.
type Point = { x: number; y: number };
type P = keyof Point; // type '"x" || "y"'
const coordinate: P = 'z' // Type '"z"' is not assignable to type '"x" | "y"'.
typeof
behaves differently when called on javascript objects, to when it is called on typescript types.
"undefined", "object", "boolean", "number", "bigint", "string", "symbol", "function"
type Language = 'EN' | 'ES';
const userLanguage: Language = 'EN';
const preferences = { language: userLanguage, theme: 'light' };
console.log(typeof preferences); // "object"
type Preferences = typeof preferences; // type '{language: 'EN''; theme: string; }'
Because the second typeof preferences
is in a type expression it is actually TypeScript's own typeof
that get called, and not javascript's.
Because keyof
is a TypeScript concept we will be calling TypeScript's verion of typeof
.
keyof typeof
will infer the type of a javascript object and return a type that is the union of its keys. Because it can infer the exact value of the keys it can return a union of their literal types instead of just returning "string".
type PreferenceKeys = keyof typeof preferences; // type '"language" | "theme"'