Skip to main content

What are union types?

1. What a union type is

Union is a type that describes a value that can be one of several possible types.

Syntax:

javascript
type MyType = TypeA | TypeB | TypeC;

Here the vertical bar | means "or".


A simple example

javascript
type ID = string | number; let userId: ID; userId = 42; // number userId = "abc123"; // string userId = true; // Error

The userId value can be a string or a number, but nothing else.


2. Why union types are needed

Union types are especially useful when:

  • a value may come in different formats (for example, an ID from a database or an API);
  • a function may accept different argument types;
  • an API response may be successful or an error.

Example: different argument types

javascript
function formatId(id: string | number) { return `ID: ${id}`; } console.log(formatId(42)); // console.log(formatId("abc123")) //

The formatId function works with both strings and numbers.


3. Union types and objects

You can combine entire structures, not just primitives:

javascript
type User = { role: "user"; name: string }; type Admin = { role: "admin"; permissions: string[] }; type Person = User | Admin;

Now the Person variable can be:

javascript
const a: Person = { role: "admin", permissions: ["delete"] }; const u: Person = { role: "user", name: "Tim" };

TypeScript checks that the object matches at least one shape.


4. Type Narrowing

When a value can be one of several types, TypeScript can figure out which type is currently in use if you check it using conditions like typeof, in, instanceof, and so on.


Example with typeof

javascript
function logId(id: string | number) { if (typeof id === "string") { console.log(id.toUpperCase()); // TS now knows id is a string } else { console.log(id.toFixed(2)); // TS now knows id is a number } }

Example with in

javascript
function printUser(person: User | Admin) { if ("permissions" in person) { console.log("Admin:", person.permissions); } else { console.log("User:", person.name); } }

TypeScript "narrows" the type itself after checking the property.


5. Union types with literals (literal unions)

A very powerful feature: you can combine specific values, not just types.

javascript
type Status = "loading" | "success" | "error"; let currentStatus: Status; currentStatus = "loading"; // currentStatus = "done"; // Error

This is often used for statuses, roles, and UI or API states.


6. Union types + functions

javascript
function printValue(value: string | number | boolean) { console.log(`Value: ${value}`); }

You can pass a string, a number, or a boolean, and TypeScript will handle it all correctly.


7. Union types vs Intersection types

TypeDescriptionExample
A | B"A or B" (one of the options)string | number
A & B"A and B" (both at once){name: string} & {age: number}

8. Example from a real project

An API response can be one of two types:

javascript
type SuccessResponse = { status: "success"; data: { id: number; name: string }; }; type ErrorResponse = { status: "error"; message: string; }; type ApiResponse = SuccessResponse | ErrorResponse; function handleResponse(res: ApiResponse) { if (res.status === "success") { console.log(res.data.name); // TS knows this is a SuccessResponse } else { console.error(res.message); // TS knows this is an ErrorResponse } }

TypeScript figures out on its own which type it is dealing with - this is called a discriminated union.


Summary

Union types (|) in TypeScript let you describe values that can belong to one of several types.

They are used when:

  • data can arrive in different formats;
  • a function accepts several argument variants;
  • API responses have different shapes;
  • fields can be restricted to specific literals ("success" | "error").

This makes the code:

  • safer (TS checks every branch),
  • more flexible (one function can handle different types),
  • and clearer for the IDE and autocomplete.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.