Keyof
keyof
extracts property list of the target type or interface.
interface Book {
name: string;
authorName: string;
price: number;
publishedDate: Date;
}
// BookKey = "name" | "authorName" | "price" | "publishedDate"
type BookKey = keyof Book;
This can be used when you want to create a function that sorts a book list. In this case, the function wants to accept one of the keys of Book type.
function sortBooks(books: Book[], key: BookKey) {
// key is "name" | "authorName" | "price" | "publishedDate"
}
Typeof
typeof
generates a type from an actual object.
const person = {
name: "Yuto",
age: 35,
};
// {
// name: string;
// age: number;
// }
type PersonType = typeof person;
// error due to typo age -> agge
const person1: typeof person = { name: "error", agge: 32 };
// not error
const person2: typeof person = { name: "OK", age: 32 };
// error because type is different
person2.age = "44";
You can extract the value list from an array to generate a type.
const LogLevelArray = [
"Trace",
"Debug",
"Info",
"Warn",
"Error",
] as const;
// "Trace" | "Debug" | "Info" | "Warn" | "Error"
type LogType = typeof LogLevelArray[number];
Combination of keyof and typeof
keyof
and typeof
can be used on the same line.
Extract enum Key value list to use for a type
It can extract the keys from an enum.
enum LogLevel {
Trace = "AA",
Debug = "BB",
Info = "CC",
Warn = "DD",
Error = "EE",
}
// "Trace" | "Debug" | "Info" | "Warn" | "Error"
type LogLevelKey = keyof typeof LogLevel;
typeof LogLevel
convert the enum to an object. The properties of the object are Trace, Debug, Info, and so on. Therefore, the properties are extracted.
You might think you can achieve the same thing by using keyof
in the following way.
// number | typeof Symbol.iterator | "toString" | "charAt" | "charCodeAt" |
// "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" |
// "search" | "slice" | ... 34 more ... | "trimRight"
type LogLevelKey2 = keyof LogLevel;
But as you can see, the result is completely different because it extracts the properties against the enum object.
Extract key list or value list from a const object
Some people prefer const object over enum because enum is not supported by JavaScript. In this case, we need to define the value type in order to restrict accepted values. Then, this keyof typeof
is useful.
const LogLevelObj = {
Trace: 10,
Debug: 20,
Info: 30,
Warn: 40,
Error: 50,
} as const;
// {
// readonly Trace: 10;
// readonly Debug: 20;
// readonly Info: 30;
// readonly Warn: 40;
// readonly Error: 50;
// }
type LogTypeObjType = typeof LogLevelObj;
// "Trace" | "Debug" | "Info" | "Warn" | "Error"
type LogTypeKey = keyof LogTypeObjType;
// 10 | 20 | 30 | 40 | 50
type LogTypeValue = typeof LogLevelObj[LogTypeKey];
If you don’t need the key type, you can also implement it in the following way.
type LogTypeValue = typeof LogLevelObj[keyof typeof LogLevelObj];
LogTypeKey
is just inlined.
Related Article
keyof typeof is used in the following article to write a better switch-case.
Comments