Skip to main content

The keyof operator

What keyof does

keyof takes the type of an object (interface, class, literal, and so on) and returns a union of all its keys as string (or numeric) literals.

Syntax:

javascript
keyof T

where T is the type whose keys you want to extract.


Example 1. A basic example

javascript
type User = { id: number; name: string; isAdmin: boolean; }; type Keys = keyof User; // "id" | "name" | "isAdmin"

keyof User returned a union of literal key types

  • "id" | "name" | "isAdmin".

How it works

keyof does not return values; it creates a type that represents the set of property names of an object.

You can think of it as an Object.keys() operator

  • but one that works at the type level, not at runtime.

Example 2. With a type with numeric keys

javascript
type Matrix = { 0: string; 1: string; 2: string; }; type K = keyof Matrix; // "0" | "1" | "2"

All keys become string literals, even if the object had numbers.


Example 3. Used with Record

javascript
type Permissions = Record<"read" | "write" | "delete", boolean>; type K = keyof Permissions; // "read" | "write" | "delete"

Example 4. Used with typeof

keyof is often used together with typeof to extract keys from a real object:

javascript
const user = { id: 1, name: "Tom", isAdmin: true, }; type UserKeys = keyof typeof user; // "id" | "name" | "isAdmin"

typeof user turns the object into its type, keyof typeof user extracts the key names.


Example 5. Paired with Index Access Types

keyof is usually used together with the indexing operator T[K].

javascript
type User = { id: number; name: string; }; type ValueOfUser = User[keyof User]; // number | string

This gives you the type of all the object's values, similar to Object.values() in JS.


Example 6. Constraining generic parameters

keyof is often used to constrain generics so that only valid keys can be passed.

javascript
function getProp<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } const user = { id: 1, name: "Alex" }; getProp(user, "id"); // OK getProp(user, "email"); // Error: "email" is not a key of user

K extends keyof T says: "K must be one of the keys of type T".


Example 7. Applying it to classes

javascript
class Point { x = 0; y = 0; move(dx: number, dy: number) {} } type Keys = keyof Point; // "x" | "y" | "move"

Example 8. With optional and readonly properties

keyof does not change property modifiers (readonly, ?)

  • it simply returns the names.
javascript
type Config = { readonly url: string; timeout?: number; }; type Keys = keyof Config; // "url" | "timeout"

Example 9. Applying it to unions

If a type is a union of objects, keyof returns the intersection of their keys (only the shared ones):

javascript
type A = { a: number; shared: string }; type B = { b: boolean; shared: string }; type Keys = keyof (A | B); // "shared"

Example 10. Applying it to arrays

Arrays in TS are objects, so they have keys too:

javascript
type K = keyof string[]; // number | "length" | "toString" | ...

So keyof returns both the numeric indices and the standard array methods.


Applying it in practice

Validating keys

javascript
function pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> { const result = {} as Pick<T, K>; for (const key of keys) { result[key] = obj[key]; } return result; } const user = { id: 1, name: "John", isAdmin: true }; const partial = pick(user, ["id", "name"]); // works

Summary

ConceptDescription
keyof TReturns a union of the key names of type T
Result typeString/numeric literal key types
Typical useK extends keyof T, T[keyof T], keyof typeof obj
JS analogSimilar to Object.keys(obj) - but works at the type level
Used inPick, Record, Partial, Omit, generic functions, and more

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.