Mapped & Template Literal Types
The last lesson used unknown and narrowing to make individual values safer. Mapped types and template literal types do the same for building new types themselves out of existing ones.
Mapped types
A mapped type loops over the keys of an existing type and transforms each one.
keyof Task produces a union of Task's property names ('id' | 'title' | 'priority'), and [K in keyof Task] loops over that union, building one new property per key. This is exactly how Partial<T> and Readonly<T> are implemented in TypeScript's own standard library, they're just mapped types with a ? or readonly added.
Template literal types
Template literal types build new string-literal types the same way JS template strings build new strings, except entirely at the type level.
${Priority}Changed distributes over every member of the Priority union, producing one literal string type per member. Capitalize<T> is a built-in intrinsic type that uppercases the first letter, useful for deriving conventional names like event handlers straight from a union you already have, instead of typing each one out by hand and letting them drift out of sync.
TIP
If you find yourself hand-writing a list of string literals that's really just "every value in this union, with a prefix or suffix," that's a template literal type waiting to replace it, one source of truth instead of two lists that can disagree.