TypeScript Tutorial
TypeScript Utility Types
Partial, Pick, Omit, and Record reshape types. They are the standard library of the type system.
Types that take types
A utility type is a built-in generic that builds a new type from an old one. You do not write a runtime function. tsc substitutes fields at compile time and then erases the result. The running program is still ordinary JavaScript objects.
C++’s STL is containers plus algorithms: vector, sort, find. TypeScript’s analog at this layer is not a list library — arrays already have methods — it is these type-level tools:Partial<User>, Pick, Omit, Record. They are the standard library of the type system.
Partial makes every field optional
Partial<User> is User with each property marked optional. Use it for a patch: you might send only age, or only name, or both. A full User still requires every field.
Example
type User = {
name: string;
age: number;
};
function applyPatch(user: User, patch: Partial<User>): User {
return {
name: patch.name ?? user.name,
age: patch.age ?? user.age,
};
}
const ada: User = { name: "Ada", age: 36 };
const older = applyPatch(ada, { age: 37 });
console.log(older.name + " " + older.age);Output is Ada 37. { age: 37 } is a valid Partial<User>. It would not be a valid User, because name is missing. That is the point of Partial.
Compile in /typescript/try (Try it in TypeScript). AddapplyPatch(ada, { age: "37" }) and tsc rejects the string.
Pick and Omit keep or drop keys
Pick<User, "name"> is a type with only that key. Omit<User, "age"> isUser without that key. The second argument is a key name (or a union of key names) as a string literal type.
Example
type User = {
name: string;
age: number;
city: string;
};
const badge: Pick<User, "name" | "city"> = {
name: "Ada",
city: "London",
};
const secret: Omit<User, "age"> = {
name: "Ada",
city: "London",
};
console.log(badge.name + " / " + badge.city);
console.log(secret.name);Both objects print a name. Neither type includes age. badge.age does not compile. Pick when you want a small public view. Omit when you want “everything except this field.”
Record maps keys to a value type
Record<K, V> is an object type whose keys are K and whose values areV. Use it for a dictionary with a known set of keys, or for a map from string to a value when you want an object instead of a Map.
Example
type Slot = "am" | "pm";
const hours: Record<Slot, number> = {
am: 9,
pm: 17,
};
console.log(hours.am);
console.log(hours.pm);
const scores: Record<string, number> = {
Ada: 95,
Kai: 88,
};
console.log(scores["Ada"]);Output is 9, 17, then 95. Leaving pm out ofhours is a type error: every Slot must be present. ARecord<string, number> is looser: any string key is allowed.
Which utility to reach for
| Utility | Result |
|---|---|
Partial<User> | Every property optional |
Pick<User, "name"> | Only the listed keys |
Omit<User, "age"> | All keys except the listed ones |
Record<K, V> | Object with keys K and values V |
There are more (Required, Readonly, ReturnType). Learn these four first. They cover patches, public views, and dictionaries. Runtime lookup by a dynamic key is the next chapter:Map.
Types only, then a real map
Utility types never allocate. Partial<User> is gone after tsc emits JavaScript. When you need a growing dictionary you iterate and look up at run time, use Map — next.
Do not memorize every utility name from a chart. Learn Partial, then Pick andOmit, then Record, and add the rest when a type error names them.