Learning TypeScript 2.x
上QQ阅读APP看书,第一时间看更新

Discriminated unions

A discriminated union (also known as tagged unions or algebraic data types) is an advanced pattern that combines string literal types, union types, type guards, and types aliases.

Discriminated unions use a type guard to narrow union types based on tests of a discriminant property (a string literal type) and furthermore extend that capability to switch statements.

The following code snippet declares three types that share a string literal property named kind:

interface Cube {
kind: "cube";
size: number;
}


interface Pyramid {
kind: "pyramid";
width: number;
length: number;
height: number;
}


interface Sphere {
kind: "sphere";
radius: number;
}

We then declare the union type of the three types declared in the preceding code snippet:

type Shape = Cube | Pyramid | Sphere;

function volume(shape: Shape) {
const PI = Math.PI;
switch (shape.kind) {
case "cube":
return shape.size ** 3;
case "pyramid":
return (shape.width * shape.height * shape.length) / 3;
case "sphere":
return (4 / 3) * PI * (shape.radius ** 3);
}
}

In the preceding function, the switch statement acts as a type guard. The type of shape is narrowed in each case clause, according to the value of the discriminant property, kind, thereby allowing the other properties of that variant to be accessed without a type assertion.