TypeScript keyof and typeof Operators
TypeScript provides powerful operators to manipulate types based on existing code or other types. Two of the most fundamental are keyof and typeof.
1. The keyof Operator
The keyof operator takes an object type and produces a string or numeric literal union of its keys.
Basic Usage
interface User {
name: string;
age: number;
location: string;
}
// "name" | "age" | "location"
type UserKeys = keyof User;
const key: UserKeys = "name"; // Valid
// const key2: UserKeys = "password"; // Error
Use Case: Generic Constraints
keyof is often used with generics to ensure a function accesses a valid property of an object.
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
const user = { name: "Alice", age: 30 };
getProperty(user, "name"); // OK
// getProperty(user, "email"); // Error: Argument of type '"email"' is not assignable...
2. The typeof Operator
In JavaScript, typeof returns a string indicating the type of a value at runtime (e.g., "string", "object").
In TypeScript, when used in a type context, typeof returns the static type of a variable or property.
Basic Usage
let s = "hello";
let n: typeof s; // n is of type 'string'
const config = {
width: 100,
height: 200,
debug: true
};
// Inferred type: { width: number; height: number; debug: boolean; }
type Config = typeof config;
3. Combining keyof and typeof
A very common pattern is to use keyof typeof together. This allows you to extract the keys of an object instance (value) as a type.
The Problem
keyof only works on types. If you have a JavaScript object (a value), you cannot use keyof directly on it.
The Solution
First, use typeof to get the type of the value, then use keyof to get the keys of that type.
const colors = {
red: "#FF0000",
green: "#00FF00",
blue: "#0000FF"
};
type ColorMap = typeof colors; // { red: string; green: string; blue: string; }
type Color = keyof ColorMap; // "red" | "green" | "blue"
// Or in one line:
type ColorKeys = keyof typeof colors;
function paint(color: ColorKeys) {
// ...
}
paint("red"); // OK
// paint("yellow"); // Error