QuestionsTypeScript

Write your own mapped + conditional type

Mapped & Conditional TypesHardTypeScript

Implement DeepReadonly<T> and explain mapped types, keyof, and conditional types.

What it tests

Type-level programming — the ceiling question that separates 'uses TS' from 'thinks in TS'.

Approach & answer

A mapped type iterates keys: { [K in keyof T]: ... }. keyof T is the union of T's keys. A conditional type A extends B ? X : Y branches at the type level. DeepReadonly maps every key to readonly and recurses into object values (conditional: if the value is an object, recurse; else leave it). This is exactly how built-ins like Partial are implemented. Two power tools sit on top of these: key remapping with `as` ({ [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K] } builds getter names from keys), and `infer` inside a conditional to capture a type (type ElementType<T> = T extends (infer U)[] ? U : never pulls the element type out of an array). Modifiers add or strip with +/-: { [K in keyof T]-?: T[K] } removes optionality (that's Required<T>), and -readonly strips readonly. Distributive conditionals matter too: when the checked type is a naked type parameter, T extends U ? ... distributes over each member of a union — wrap in [T] to opt out. These are the building blocks of every advanced library type.

Use this technique when

Library authoring, deriving types (form types from a schema, immutable state trees), transforming API types into UI types without hand-writing them.

References

ts