Advanced Patterns

keyof T

The keyof type operator produces a union of all known public property keys of a type, enabling type-safe property access patterns.

Definition

TypeScript
type Keys = keyof { name: string; age: number };
// "name" | "age"

Examples

Property Access
interface User {
  id: number;
  name: string;
  email: string;
}

type UserKey = keyof User;
// "id" | "name" | "email"

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user: User = { id: 1, name: "Alice", email: "[email protected]" };
const name = getProperty(user, "name"); // string
const id = getProperty(user, "id");     // number
Constrained Generics
function pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
  const result = {} as Pick<T, K>;
  keys.forEach((key) => {
    result[key] = obj[key];
  });
  return result;
}

const user = { id: 1, name: "Alice", email: "[email protected]", password: "secret" };
const safe = pick(user, ["id", "name", "email"]);
// { id: number; name: string; email: string }
Exhaustive Checking
interface Theme {
  primary: string;
  secondary: string;
  background: string;
  text: string;
}

const themeKeys: (keyof Theme)[] = [
  "primary", "secondary", "background", "text",
];

function validateTheme(theme: Record<string, string>): theme is Theme {
  return themeKeys.every((key) => typeof theme[key] === "string");
}

Common Use Cases

  • 1Type-safe property access with indexed types
  • 2Constraining generic type parameters to valid keys
  • 3Building dynamic property lookup functions
  • 4Iterating over known properties for validation
  • 5Creating mapped types and utility type definitions

Understanding keyof T

The keyof type operator takes an object type and produces a union of its known public property keys as string literal types. For an interface with properties "name", "age", and "email", keyof produces "name" | "age" | "email".

keyof is fundamental to TypeScript's type-safe property access pattern. The generic function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] is the canonical example: it accepts any object and any valid key for that object, and the return type T[K] (indexed access type) automatically resolves to the correct property type.

This pattern eliminates an entire class of bugs. Without keyof, accessing obj[key] would require key to be typed as string, and the return type would be any. With keyof, the compiler verifies that key is actually a valid property name and knows the exact type of the returned value.

keyof interacts with index signatures in specific ways. If a type has a string index signature, keyof produces string | number (since numeric keys are a subset of string keys in JavaScript). If it has a numeric index signature, keyof produces number. For types with only known properties, keyof produces the union of literal key types.

keyof is the building block of mapped types. The syntax [K in keyof T] iterates over every key, and this iteration pattern powers Partial, Required, Readonly, Pick, and all other mapped utility types. Understanding keyof is essential to understanding how these utility types work.

Combined with template literal types, keyof enables advanced key transformations. You can generate getter names, event handler names, or any other derived key pattern from the original keys of a type.

Related Types

More Advanced Patterns

Explore TypeScript Types

Browse our complete reference of 30 TypeScript utility types with definitions, examples, and explanations.