Andrew's Digital Garden

Unions, intersections, and extending interfaces

Some crucial terminology in Typescript.

Unions

Unions use the | operator to form a type from two or more other types. The value can be any of those types - it's similar to an 'OR'. Each type is known as a union member.

type id = number | string

If there is a value that is a union type, we can only access members that are common to all types in the union.

interface Bird { fly(): void; layEggs(): void; } interface Fish { swim(): void; layEggs(): void; } type Animal = Bird | Fish // only Animal.layEggs exists, as it's the common field

Intersections

Intersections use the & operator to form a type combining all of the members of existing types. It's similar to an 'AND', in some regards.

interface Colorful { color: string; } interface Circle { radius: number; } type ColorfulCircle = Colorful & Circle; const c: ColorfulCircle = { color: 'red', radius: 10 };

Note that the intersection type is a little different when you're dealing with primitive types, as there is often no intersection between the two, e.g:

type id = number & string // id: never, as there's no intersection between the two types type Animal = 'lion' | 'tiger'; type Domestic = 'bee' | 'cow'; type DomesticAnimal = Animal & Domestic; // DomesticAnimal: never

Extends

The extends keyword is similar to intersections, allowing one to add additional members to an existing type.

interface Colorful { color: string; } interface Circle { radius: number; } interface ColorfulCircle extends Colorful, Circle {} const c: ColorfulCircle = { color: 'red', radius: 10 };

The two (extends and intersections) are similar, but have differences around overriding properties, working with dynamic properties, and more.

One advantage of the latter (interfaces), is that it will throw an error if a member present on both interfaces doesn't match:

interface A { a: number; foo: string; } interface B { b: boolean; foo: number; } // Error: Types of property 'foo' are incompatible. interface AB extends A { foo: number; }

TS Repro Link

[[ts]]

Unions, intersections, and extending interfaces