iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

TS keyof

keyof T gives you the union of T's property keys as literal types. Pairs perfectly with generic constraints to build type-safe property accessors.

Basics

TS
type Point = { x: number; y: number };
type Axis  = keyof Point;       // 'x' | 'y'

const a: Axis = 'x';
// const b: Axis = 'z';          // ✗ error

Type-safe property access

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

const user = { id: 1, name: 'Ada' };
const id   = getProp(user, 'id');     // number
const name = getProp(user, 'name');   // string
// getProp(user, 'email');             // ✗ error — not a key

Index signatures

TS
type StringMap = { [key: string]: number };
type K = keyof StringMap;        // string | number   (indexable by either at runtime)

keyof on a Record

TS
type Colors = Record<'red' | 'green' | 'blue', string>;
type Color  = keyof Colors;     // 'red' | 'green' | 'blue'

keyof + typeof — strongly typed enums from values

TS
const STATUSES = {
    Paid:     'paid',
    Pending:  'pending',
    Refunded: 'refunded',
} as const;

type StatusKey   = keyof typeof STATUSES;       // 'Paid' | 'Pending' | 'Refunded'
type StatusValue = typeof STATUSES[StatusKey];   // 'paid' | 'pending' | 'refunded'

Common mistake — keyof object

TS
// "object" has no known keys
type K = keyof object;     // never

// You almost always want keyof of a SPECIFIC shape.
Tip: keyof + generic constraint is the building block of every "typed pluck/get/set" helper you'll ever need. Memorise function get<T, K extends keyof T>(o: T, k: K): T[K] — it pays dividends forever.

Example

Example
type Point = { x: number; y: number };
type Axis = keyof Point;        // 'x' | 'y'

function get<K extends keyof Point>(p: Point, k: K): Point[K] {
  return p[k];
}
console.log(get({ x: 3, y: 4 }, 'x'));
Try it Yourself »

Exercise

Operator that gives the union of T's keys.

type K = Point;

Test yourself

Q1. For "type Point = {x:number;y:number}", "keyof Point" is…
Q2. Pair with extends for type-safe getters: "K extends keyof T" then "T[K]" gives…
Q3. "keyof object" is…

Discussion

Loading…