type UserId = string;
type Coordinate = { x: number; y: number };
type StringOrNumber = string | number;
type Callback = (data: unknown) => void;
const origin: Coordinate = { x: 0, y: 0 };
const userId: UserId = "usr_9f3a";
output
// Type aliases create a name for any type expression
Note Type aliases and interfaces overlap for object shapes, but type aliases can also name unions, tuples, primitives, and function types. Unlike interfaces, type aliases cannot be re-declared for merging. Use interfaces for object shapes that might be extended; use type aliases for everything else.
type aliastype keywordcustom typenamed typetype vs interface
Union Types
syntax
type Name = TypeA | TypeB | TypeC;
example
type Status = "pending" | "active" | "archived";
type ApiResponse = SuccessResult | ErrorResult;
interface SuccessResult {
ok: true;
data: unknown;
}
interface ErrorResult {
ok: false;
errorCode: number;
message: string;
}
function handleResponse(res: ApiResponse) {
if (res.ok) {
console.log(res.data); // narrowed to SuccessResult
} else {
console.error(res.message); // narrowed to ErrorResult
}
}
output
// Union means 'one of these types' — must narrow before accessing specific members
Note You can only access properties common to ALL members of a union without narrowing first. Use a shared discriminant property (like 'ok' above) to let TypeScript narrow automatically in conditionals.
union typeor typemultiple typeseither typediscriminated union
Intersection Types
syntax
type Name = TypeA & TypeB;
example
type WithId = { id: string };
type WithTimestamps = { createdAt: Date; updatedAt: Date };
type UserRecord = WithId & WithTimestamps & {
email: string;
displayName: string;
};
const user: UserRecord = {
id: "usr_001",
email: "[email protected]",
displayName: "Dev User",
createdAt: new Date(),
updatedAt: new Date(),
};
output
// Intersection combines all properties from all types
Note Intersection means 'all of these combined'. If two types have the same property with incompatible types, the intersected property becomes never (which usually means a mistake). Intersections are great for mixin-style composition.
intersection typecombine typesand typemerge typesmixin type
Literal Types
syntax
type Name = "exactValue" | "anotherValue";
type Name = 0 | 1 | 2;
example
type Direction = "north" | "south" | "east" | "west";
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;
function move(direction: Direction, steps: number) {
console.log(`Moving ${direction} by ${steps}`);
}
move("north", 3); // OK// move("up", 3); // Error: Argument of type '"up"' is not assignable
output
// Literal types restrict a value to an exact set of allowed values
Note Literal types turn strings, numbers, or booleans into specific-value types. Combined with unions, they create powerful enumerations without the overhead of enum. const assertions (as const) automatically infer literal types.
literal typestring literalexact value typespecific valuesenum alternative
Note Template literal types construct new string types from combinations. They distribute over unions — every combination is produced. Built-in string manipulation types (Capitalize, Uppercase, Lowercase, Uncapitalize) work inside template literals. Extremely powerful for typing DSLs and API patterns.
template literal typestring pattern typedynamic string typestring manipulation type
Generic Type Aliases
syntax
type Name<T> = { ... };
type Name<T, U = DefaultType> = ...;
example
type ApiResult<T> = {
data: T;
status: number;
timestamp: Date;
};
type Nullable<T> = T | null;
type Pair<A, B = A> = [A, B];
const userResult: ApiResult<{ name: string }> = {
data: { name: "Priya" },
status: 200,
timestamp: new Date(),
};
const point: Pair<number> = [10, 20]; // both numberconst labeled: Pair<string, number> = ["x", 42];
output
// Generic aliases accept type parameters just like functions accept value parameters
Note Generic type aliases are essential for building reusable type utilities. Default type parameters (B = A) make common cases convenient while keeping the alias flexible. You can also add constraints with extends.
generic type aliasparameterized typereusable typetype with generic