keyof, typeof, and infer
TL;DR
These three operators are the foundation of advanced TypeScript programming:
typeof: Extracts the type from a JavaScript variable.keyof: Extracts a union of keys from a TypeScript object type.infer: Extracts a type from inside another type (used in conditional types).
1. The typeof Operator
In standard JavaScript, typeof x returns a string like "number".
In the Type Context of TypeScript, typeof takes a JavaScript variable and generates a TypeScript Type based on its shape.
const defaultConfig = { port: 8080, secure: true };
// We don't want to manually write an interface. Let TS do it!
type Config = typeof defaultConfig;
// Type Config is: { port: number, secure: boolean }
2. The keyof Operator
It takes an object type (not a variable) and produces a string or numeric literal union of its keys.
interface User {
id: number;
name: string;
}
type UserKeys = keyof User;
// Type UserKeys is exactly: "id" | "name"
// Great for safe property access functions!
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
3. The infer Keyword
infer can only be used inside the condition of a Conditional Type (T extends ...). It tells TypeScript: “I don’t know what this inner type is, but figure it out, save it to a temporary variable, and let me use it.”
// "If T is an Array of some type Item, return Item. Otherwise, return T."
type UnpackArray<T> = T extends Array<infer Item> ? Item : T;
type A = UnpackArray<string[]>; // Evaluates to 'string'
type B = UnpackArray<number>; // Evaluates to 'number'
Common Interview Questions
Can you combine keyof and typeof?
Yes! It is extremely common when you have a static JavaScript object (like an enum replacement) and you want a type representing all its keys.
const Colors = { Red: "#f00", Blue: "#00f" };
type ColorNames = keyof typeof Colors; // "Red" | "Blue"
How do you extract the Return Type of a function using infer?
This is how the built-in ReturnType<T> utility works:
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
It asks: “Does T look like a function? If yes, infer whatever it returns into R, and give me R.”