xxxxxxxxxx
// Example of a discriminated union in TypeScript
interface Square {
kind: "square";
sideLength: number;
}
interface Circle {
kind: "circle";
radius: number;
}
type Shape = Square | Circle;
function calculateArea(shape: Shape): number {
switch (shape.kind) {
case "square":
return shape.sideLength ** 2;
case "circle":
return Math.PI * shape.radius ** 2;
default:
throw new Error("Invalid shape");
}
}
const square: Square = {
kind: "square",
sideLength: 5
};
const circle: Circle = {
kind: "circle",
radius: 3
};
console.log(calculateArea(square)); // Output: 25
console.log(calculateArea(circle)); // Output: 28.274333882308138
xxxxxxxxxx
// Object unions with variants of a similiar property, but different
// key names. Need to add a common property to connect them.
interface Circle {
kind: "circle";
radius: number;
}
interface Square {
kind: "square";
sideLength: number;
}
type Shape = Circle | Square;
// TypeScript can now narrow out the members
function getArea (shape: Shape) {
if (shape.kind === "circle") {
return Math.PI * shape.radius ** 2 // safely accessing shape.radius
}
}
// Alternatively use a switch statement
switch(shape.kind) {
case 'circle':
return Math.PI * shape.radius ** 2
case 'square':
return shape.sideLength ** 2
xxxxxxxxxx
// Union Type: function reacts depending on x type (array of string OR string)
function welcomePeople(x: string[] | string) {
if (Array.isArray(x)) {
console.log("Hello, " + x.join(" and ")); // 'x' is 'string[]'
} else {
console.log("Welcome lone traveler " + x); // 'x' is 'string'
}
}
xxxxxxxxxx
type Circle = { kind: 'circle'; radius: number };
type Rect = { kind: 'rect'; width: number; height: number };
type Shape = Circle | Rect;
function getArea(shape: Shape) {
return shape.kind === 'circle' ?
Math.PI * shape.radius ** 2
: shape.width * shape.height;
}