BeCuriouzLearn something new every day
Indexed Access Types: Ask a Type for a Property's Type
💡 T[K] performs a type-level property lookup, extracting the type at key K and keeping it permanently in sync with its source type.
Recall from earlier cards that keyof T gives you a union of an object type's keys. Indexed access types are the natural next step: instead of asking "what are the keys?", you ask "what type lives at this key?" The syntax mirrors normal property access, but it happens in the type space, not at runtime: T[K] looks up the type stored at property K of type T.
type User = { id: number; name: string; admin: boolean };
type Id = User["id"]; // number
type Name = User["name"]; // stringThe key inside the brackets is itself a type, not a value — which is why you can pass a union of keys and get back a union of the corresponding types. Combined with keyof, T[keyof T] gives you the union of all value types in the object:
type IdOrName = User["id" | "name"]; // number | string
type AllValues = User[keyof User]; // number | string | booleanThe real power is that the lookup stays linked to the source. If you rename User.name to a string | null, every User["name"] updates automatically — no duplicated, drifting type annotations. This also works on arrays: T[number] indexes an array or tuple type to extract its element type, e.g. type Item = Product[], then Product[] becomes Item[number] → Product. Indexed access is the building block that later makes mapped and conditional types feel effortless.