The keyof
and typeof
keyword are very useful keywords that you can use for many interesting things. One of which is creating types from the keys of an object.
The typeof
keyword exists in the JavaScript world as well as the TypeScript world and it does similar things: get the type of a value.
The keyof
keyword creates a type out of the keys of an object type. Let’s see examples:
type Person = {
name: string;
age: string;
languages: string[]
}
let /**/key/**/: keyof Person
key: 'name' | 'age' | 'languages' In this example, key
would be a union type of the properties (keys) in the Person
Type:
type Person = {
name: string;
age: string;
languages: string[]
}
let key: keyof Person
key = 'name' // fine
/**/key/**/ = 'something'
Type '"something"' is not assignable to type 'keyof Person' Let’s say we had an object like this:
const dutchTranslation = {
"hello": "hoi",
"good morning": "goedemorgen",
"difficult": "moeilijk",
"grandma": "oma"
}
The dutchTranslation
object has key-value pairs where the key is the english word and the value is the dutch word. How can we create a key type from the keys in this object? You might think keyof
:
const dutchTranslation = {
"hello": "hoi",
"good morning": "goedemorgen",
"difficult": "moeilijk",
"grandma": "oma"
}
type /**/TranslationKey/**/ = keyof dutchTranslation
'dutchTranslation' refers to a value, but is being used as a type here. keyof
does not work because it expects a type, not a value. In keyof dutchTranslation
, dutchTranslation
points to a value. So, what we have to do first is get the type of dutchTranslation
. Here, we can use `typeof:
const dutchTranslation = {
"hello": "hoi",
"good morning": "goedemorgen",
"difficult": "moeilijk",
"grandma": "oma"
}
type DutchTranslationType = typeof dutchTranslation
DutchTranslationType
will look like this:
{
"hello": string;
"good morning": string;
"difficult": string;
"grandma": string;
}
Now that we have the type, we can use keyof
:
const dutchTranslation = {
"hello": "hoi",
"good morning": "goedemorgen",
"difficult": "moeilijk",
"grandma": "oma"
}
type DutchTranslationType = typeof dutchTranslation
type /**/TranslationKey/**/ = keyof DutchTranslationType
TranslationKey: 'hello' | 'good morning' | 'difficult' | 'grandma' TranslationKey
holds a union type of the keys in the object. You can also combine keyof
and typeof
like this:
type TranslationKey = keyof typeof dutchTranslation