TypeScript's standard library (lib.es5.d.ts) defines utility types with the operators of this section: Partial is a mapped type, Exclude a conditional type, NoInfer a compiler intrinsic. Learn them before writing your own:
| Utility | Result | Since |
|---|---|---|
| Partial<T>, Required<T> | All keys optional, required | 2.1, 2.8 |
| Readonly<T> | Top-level keys readonly | 2.1 |
| Record<K, V> | Keys K, values V | 2.1 |
| Pick<T, K>, Omit<T, K> | Keep keys K, drop keys K | 2.1, 3.5 |
| Exclude<U, M> | Union minus members of M | 2.8 |
| NonNullable<T> | Drops null, undefined | 2.8 |
| ReturnType<F> | A function's return type | 2.8 |
| Parameters<F> | A function's parameter tuple | 3.1 |
| Awaited<T> | Unwrapped promise result | 4.5 |
| NoInfer<T> | Blocks inference here | 5.4 |
interface User { id: number; name: string; email: string; role: "admin" | "member" }
type NewUser = Omit<User, "id">; // a signup form's payload
type UserPatch = Partial<Pick<User, "name" | "email">>; // { name?: string; email?: string }
const roleLabels: Record<User["role"], string> = { admin: "Administrator", member: "Member" };
declare function updateUser(id: number, patch: UserPatch): Promise<User>;
type Updated = Awaited<ReturnType<typeof updateUser>>; // User
function choose<T extends string>(sizes: T[], fallback: NoInfer<T>): T {
return sizes[0] ?? fallback;
}
const draft: NewUser = { id: 7, name: "Ada", email: "ada@example.com", role: "admin" };
updateUser(1, { role: "admin" });
choose(["sm", "md", "lg"], "xl");Output
users.ts(10,26): error TS2353: Object literal may only specify known properties, and 'id' does not exist in type 'NewUser'. users.ts(11,17): error TS2353: Object literal may only specify known properties, and 'role' does not exist in type 'Partial<Pick<User, "email" | "name">>'. users.ts(12,28): error TS2345: Argument of type '"xl"' is not assignable to parameter of type '"lg" | "md" | "sm"'.
Without NoInfer, TypeScript would also infer T from "xl" and accept it. Record<User["role"], string> forces a label for every role, so adding "guest" to User breaks the build until roleLabels is updated.