TypeScript's basic data types are the seven JavaScript primitives, string, number, bigint, boolean, symbol, null and undefined, written in lowercase. On top of those it adds special types (any, unknown, never, void, object), structures such as arrays, tuples and enums, and ways to combine types: literal types, unions and intersections.
| Group | Types | Use it for |
|---|---|---|
| Primitives | string, number, bigint, boolean, symbol, null, undefined | Single values |
| Special | any, unknown, never, void, object | Describing the edges of the type system |
| Structures | Arrays, tuples, enums, object types | Groups of values |
| Combinations | Literal types, unions, intersections | Precise or flexible shapes |
Updated
Search the reference by name or filter it by group. Every row has a one-line example you can paste into a .ts file, and the notes column flags the behaviour that trips people up, such as the gap between void and undefined or why unknown is safer than any.
Showing 21 of 21 types
| Type | Group | Example | Note |
|---|---|---|---|
string | Primitives | let title: string = "Pricing"; | Text of any length. Template literals are strings too. |
number | Primitives | let price: number = 19.99; | Integers and decimals alike, including NaN and Infinity. |
bigint | Primitives | let views: bigint = 9007199254740993n; | Whole numbers beyond the safe integer range. The n suffix needs an ES2020 target. |
boolean | Primitives | let isLive: boolean = true; | Only true or false. |
symbol | Primitives | const tag: symbol = Symbol("tag"); | Each call to Symbol() makes a unique value. |
null | Primitives | let picked: string | null = null; | With strictNullChecks on, null must be listed in the type to be allowed. |
undefined | Primitives | let note: string | undefined; | The value of a declared but unassigned variable and of a missing optional property. |
any | Special | let raw: any = JSON.parse(text); | Turns off checking for the value. noImplicitAny reports places where it creeps in unannounced. |
unknown | Special | let input: unknown = JSON.parse(text); | Holds any value but allows nothing until you narrow it. |
never | Special | function fail(msg: string): never { throw new Error(msg); } | No value ever has this type: functions that always throw, and unions with nothing left. |
void | Special | function log(msg: string): void { console.log(msg); } | A return value that should be ignored. Not the same as undefined. |
object | Special | let target: object = { id: 1 }; | Any non-primitive: objects, arrays and functions. |
Array | Structures | let tags: string[] = ["a", "b"]; | string[] and Array<string> mean the same thing. |
readonly array | Structures | let ids: readonly number[] = [1, 2]; | Same as ReadonlyArray<number>. push and other mutating methods are removed. |
Tuple | Structures | let pair: [string, number] = ["age", 36]; | Fixed length with a type per position. Optional elements go at the end: [number, number?]. |
enum | Structures | enum Role { Admin, Editor } | Generates a real object at runtime, unlike most TypeScript syntax. |
Object type | Structures | let user: { id: number; name?: string }; | Describes properties inline. Name it with type or interface to reuse it. |
Function type | Structures | let onSave: (id: number) => void; | Parameter and return types. Prefer this to the loose Function type. |
Literal type | Combinations | let align: "left" | "right" = "left"; | Exact values instead of the whole primitive. |
Union | Combinations | let id: number | string = 42; | One of several types. Narrow with typeof, in or a shared field before using members. |
Intersection | Combinations | type Admin = User & { permissions: string[] }; | All of the types at once. Mostly used to merge object types. |
Each check removes possibilities. Inside the final branch the compiler knows value is a string.
function toLabel(value: unknown): string {
if (typeof value === "string") return value.trim();
if (typeof value === "number") return value.toFixed(2);
if (value === null || value === undefined) return "n/a";
return JSON.stringify(value);
}If a new status joins the union, the assignment to never stops compiling until a case is added for it.
type Status = "draft" | "live" | "archived";
function badge(status: Status): string {
switch (status) {
case "draft": return "Draft";
case "live": return "Live";
case "archived": return "Archived";
default: {
const unreachable: never = status;
return unreachable;
}
}
}
The lowercase primitive types line up with what JavaScript's typeof operator reports at runtime, which is why typeof checks narrow them so cleanly. null is the exception: typeof null is "object", so check it with === null.
bigint needs a compile target of ES2020 or later for the 123n literal syntax. symbol values are unique even when created with the same description.
any and unknown sit at the top: every value fits in them. never sits at the bottom: no value fits, and it fits into every other type. void is about return values, and object is about ruling out primitives.
Knowing which edge you are at makes compiler messages readable. An error that mentions never after narrowing usually means a branch the code believes can never run.
A literal type narrows a primitive to exact values, such as "left" | "right". A union says a value is one of several types; an intersection says it is all of them at once, which is how you merge two object types.
Unions of string literals often replace enums, because they are erased completely and read naturally in code. The enums guide on this site compares both.
Seven, the same as JavaScript: string, number, bigint, boolean, symbol, null and undefined. number covers both integers and decimals; there is no separate int or float type.
Both accept any value. any lets you do anything with it, so mistakes pass silently. unknown lets you do nothing until you narrow it with a check such as typeof, which makes it the safe choice for untrusted data.
never describes values that cannot occur: the return type of a function that always throws, and what is left of a union after every member has been handled. That second use powers exhaustiveness checks.
No. void is the return type of a function whose return value should be ignored. A function typed as returning void may be given a callback that returns something, while undefined means the value really is undefined.
object means any non-primitive value, such as objects, arrays and functions. {} means any value except null and undefined, primitives included. The global Object type is rarely useful; prefer object or a specific object type.
Related: TypeScript enums and alternatives, TypeScript vs JavaScript, TypeScript interfaces, TypeScript Record type, TypeScript classes.
Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.
We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.