"Record describes dictionaries. Readonly describes immutability. Both are everyday utilities."
Record<K, V> — dictionary type
Record<K, V> creates an object type where keys are of type K and values are of type V. Record<string, number> is a dictionary mapping any string to a number. Record<'a' | 'b' | 'c', User> is an object that must have exactly the keys 'a', 'b', 'c', each mapping to a User.
Record is the canonical type for dictionary-shaped data — phone books, lookup tables, configuration maps. When K is a literal union, Record acts like an enum-keyed map; when K is string, it's an open dictionary.
Readonly<T> — make every field readonly
Readonly<User> takes User and produces a type where every field has the readonly modifier. Useful for function parameters where you want to signal 'I won't mutate this' and for freezing configuration shapes.
Like Partial, it's shallow — the readonly applies to top-level fields only. For deep readonly, you'd write a recursive mapped type or use a library like ts-toolbelt's DeepReadonly.
Pick, you can express almost any shape relationship using utility types alone.