More Utility Types
Beyond reshaping objects, TypeScript's built-in utilities can filter unions, strip out null, and pull types out of functions, classes and promises. These are the tools for deriving types from code you already have instead of writing them twice.
Exclude and Extract
Both work on union types. Exclude<U, X> removes the members of U that are assignable to X; Extract<U, X> keeps only those members:
type Status = "idle" | "loading" | "success" | "error"; type Busy = Extract<Status, "loading">; type Settled = Exclude<Status, "idle" | "loading">; type Mixed = string | number | (() => void); type Callable = Extract<Mixed, Function>; type Data = Exclude<Mixed, Function>; const s: Settled = "error"; const d: Data = 42; console.log(s, d);
error 42
Settled is "success" | "error", and Data is string | number. Compare with Omit, which removes properties from an object type; Exclude removes members from a union.
NonNullable
NonNullable<T> removes null and undefined from a type:
type MaybeName = string | null | undefined; type Name = NonNullable<MaybeName>; function shout(n: Name) { return n.toUpperCase(); } console.log(shout("ok"));
OK
ReturnType and Parameters
These extract the types from a function's signature. They're invaluable when a library exports a function but not the types it uses:
function createSession(userId: number, opts: { ttl: number; remember: boolean }) { return { token: `t-${userId}`, expiresIn: opts.ttl, remember: opts.remember }; } type Session = ReturnType<typeof createSession>; type SessionArgs = Parameters<typeof createSession>; type SessionOpts = Parameters<typeof createSession>[1]; const opts: SessionOpts = { ttl: 3600, remember: true }; const args: SessionArgs = [7, opts]; const session: Session = createSession(...args); console.log(session);
{ token: 't-7', expiresIn: 3600, remember: true }Parameters returns a tuple of the parameter types, so [1] picks the second one. Note the typeof: these utilities take a function type, and typeof createSession turns the function value into its type.
Awaited
Awaited<T> unwraps the value type of a promise, the same way await does — including nested promises:
async function loadUser() { return { id: 1, name: "Ana" }; } type UserPromise = ReturnType<typeof loadUser>; type User = Awaited<UserPromise>; const cached: User = { id: 2, name: "Bo" }; loadUser().then(u => console.log(u.name, cached.name));
Ana Bo
UserPromise is Promise<{ id: number; name: string }>, and Awaited gives you the object inside. Awaited<ReturnType<typeof fn>> is a very common combination for async functions.
Classes: InstanceType and ConstructorParameters
class Connection { constructor(public host: string, public port: number) {} } type ConnArgs = ConstructorParameters<typeof Connection>; type Conn = InstanceType<typeof Connection>; function connectAll(list: ConnArgs[]): Conn[] { return list.map(args => new Connection(...args)); } console.log(connectAll([["db.local", 5432]])[0].port);
5432
For a class you declared yourself, InstanceType<typeof Connection> is the same as just writing Connection. It's mainly useful in generic code that receives a class as a value.
String-case utilities
Four intrinsic types transform string literal types: Uppercase, Lowercase, Capitalize and Uncapitalize. They're mostly used with template literal types (lesson 30):
type Event = "click" | "focus"; type Handler = `on${Capitalize<Event>}`; const handlers: Record<Handler, () => void> = { onClick: () => console.log("clicked"), onFocus: () => console.log("focused"), }; handlers.onClick();
clicked
NoInfer
Added in TypeScript 5.4, NoInfer<T> tells the compiler not to use a particular argument when inferring a type parameter:
function pick<T extends string>(options: T[], fallback: NoInfer<T>): T { return options[0] ?? fallback; } pick(["small", "large"], "small"); pick(["small", "large"], "medium");
error TS2345: Argument of type '"medium"' is not assignable to parameter of type '"small" | "large"'.
Without NoInfer, TypeScript would infer T from both arguments, widen it to include "medium", and accept the typo.
Quick reference
| Utility | Works on | Result |
|---|---|---|
Exclude<U, X> | Unions | Members of U not assignable to X |
Extract<U, X> | Unions | Members of U assignable to X |
NonNullable<T> | Any | T without null/undefined |
ReturnType<F> | Function types | Return type |
Parameters<F> | Function types | Tuple of parameter types |
Awaited<T> | Promises | Resolved value type |
InstanceType<C> | Class types | Instance type |
ConstructorParameters<C> | Class types | Tuple of constructor parameter types |
NoInfer<T> | Type parameters | Blocks inference from that position |