`keyof`

The Keys of a Type, as a Union

`keyof`

`keyof T` is a union of T's property names. The foundation of type-safe property access.

4 min read Level 2/5 #typescript#keyof#advanced
What you'll learn
  • Use `keyof` to get a property-name union
  • Combine with generics for type-safe access
  • Recognize `keyof` on union types

keyof T evaluates to a union of T’s property names. The foundation of type-safe property access.

The Basics

type User = {
  name: string;
  age: number;
  admin: boolean;
};

type UserKeys = keyof User;
// "name" | "age" | "admin"

Type-Safe Property Access

The classic use:

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

const u: User = { name: "Ada", age: 36, admin: true };

get(u, "name");      // string
get(u, "age");        // number
get(u, "admin");      // boolean
get(u, "missing");    // ✗ Argument of type '"missing"' is not assignable...

K extends keyof T restricts the key argument to valid keys. The return type T[K] is the type of that specific property.

keyof on Records

type Scores = Record<string, number>;
type K = keyof Scores;   // string | number — `Record<string, ...>` allows numeric keys too

Record’s keys aren’t necessarily literal — keyof reflects that.

keyof on Index Signatures

type Settings = { [key: string]: boolean };
type K = keyof Settings;   // string | number

A plain string index signature includes number in its keyof (legacy JS thing — number keys coerce to strings).

keyof on a Union

type A = { x: number; y: number };
type B = { x: number; z: number };

type K = keyof (A | B);   // "x"  (the common keys)

keyof (A | B) is the INTERSECTION of keyof A and keyof B — only keys that exist on every member.

keyof (A & B) is the UNION — all keys from both.

keyof with No Keys

type Empty = {};
type K = keyof Empty;   // never (no keys exist)

Up Next

typeof — getting the type of a value.

`typeof` →