Skip to content

Unions, Literals, and Narrowing

let id: string | number;

A union means a value can be one of multiple allowed types.


type Status = "pending" | "success" | "failed";

Literal types are specific allowed values, not just broad categories.


You narrow a type by checking it before use.

function printValue(value: string | number) {
if (typeof value === "string") {
console.log(value.toUpperCase());
} else {
console.log(value.toFixed(2));
}
}

typeof

For primitive checks like string, number, boolean.

instanceof

For class-based checks.

in

Check if property exists in object.

Custom guard

Reusable function returning value is Type.


type ApiResponse<T> =
| { status: "success"; data: T }
| { status: "error"; message: string };
function handleResponse<T>(response: ApiResponse<T>) {
if (response.status === "success") {
return response.data;
}
throw new Error(response.message);
}
graph TD A[ApiResponse] --> B{status} B -->|success| C[data] B -->|error| D[message]

type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function area(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius * shape.radius;
case "square":
return shape.side * shape.side;
default: {
const _never: never = shape;
return _never;
}
}
}

If a new shape type is added and not handled, TypeScript reports an error at _never.