`type Name<T> = ...`
Generic Type Aliases
Type aliases can take type parameters too — `type Result<T> = ...`. Build reusable shapes parameterized by the contained type.
What you'll learn
- Author generic type aliases
- Build `Result<T, E>`-style helpers
- Recognize generic interfaces
A type alias can take parameters too. The result — a reusable shape that depends on what’s inside.
The Syntax
type Maybe<T> = T | null;
const name: Maybe<string> = null;
const age: Maybe<number> = 36; Same idea as a generic function — declare in <...>, use as a
type.
A Useful Result Type
type Result<T, E = Error> =
| { ok: true; data: T }
| { ok: false; error: E };
function divide(a: number, b: number): Result<number, string> {
if (b === 0) return { ok: false, error: "Division by zero" };
return { ok: true, data: a / b };
} Discriminated union from chapter 2, now generic over the success and error types.
A Common Wrap
type AsyncData<T> =
| { status: "loading" }
| { status: "success"; data: T }
| { status: "error"; error: Error };
const users: AsyncData<User[]> = { status: "loading" }; Models the three states of any async fetch.
Generic Interfaces
interface Pair<A, B> {
first: A;
second: B;
}
const p: Pair<string, number> = { first: "Ada", second: 36 }; Same idea as a generic type — but only for object shapes (and
with declaration merging if you need it).
Multiple Parameters
type Dict<V> = Record<string, V>;
type KV<K extends string, V> = Record<K, V>; Record<K, V> itself is a built-in generic — keys of K with values
of V.
Reusing the Parameter
The same parameter can appear multiple times:
type Two<T> = [T, T];
const points: Two<number>[] = [
[1, 2],
[3, 4],
]; Constraints Work Here Too
type WithId<T extends { id: string }> = T & { added: Date }; Same extends constraint syntax.
Up Next
Default type arguments — <T = SomeDefault>.