keyof and indexed access types
Read keys and value types straight off a type.
keyof T gives you the union of a type's property names, and the indexed access T[K] reads the value type stored at those keys β together they let you write lookups that stay correct as the underlying type changes.
keyof gives you the key union
keyof T evaluates to a union of T's public property names as literal types. For interface User { id: string; age: number }, keyof User is 'id' | 'age'. Because it is computed from the type, the union updates automatically when you add or remove a property β there is no separate list of names to keep in sync. For an object with string keys you get string, and for an array or tuple you also get the numeric index keys plus the inherited Array members.
Indexed access reads the value type
T[K] is the indexed access (or lookup) type: it asks "what is the type of the value at key K?" So User['id'] is string and User['age'] is number. The key can itself be a union β User['id' | 'age'] is string | number β and T[keyof T] therefore reads the union of all value types in T. This mirrors the runtime obj[key] expression, but at the type level.
A type-safe getter ties them together
The classic pairing is a generic get(obj, key): constrain the key parameter with K extends keyof T and declare the return type as T[K]. Now the compiler rejects keys that don't exist and infers the exact value type at the call site β get(user, 'age') is typed number, not a widened string | number. The two features are most powerful together: keyof to constrain the key, indexed access to describe the result.
Arrays: T[number] is the element type
Indexing a tuple or array type with the literal type number yields its element type: for type Nums = number[], Nums[number] is number, and for a tuple [string, boolean], T[number] is string | boolean. Combined with typeof over an as const array, (typeof arr)[number] extracts a union of the array's literal values β a common way to derive a union from a single source list.
Try it 5 examples
keyof as a union of keys
TSintroThe UserKey[] array accepts only the three literal names keyof User produced, so keys.join(', ') prints id, name, age and count: 3 β adding a field to User would extend the union automatically, with no separate list to update.