Pattern Matching
Given the following matchbox factory:
export const shapes = matchboxFactory({ Circle: (radius: number) => ({ radius }), Square: (side: number) => ({ side }), Rectangle: (width: number, height: number) => ({ width, height }),});
match()
Method
Section titled “match() Method”The most powerful feature of tagged unions created with matchboxFactory
is exhaustive pattern matching with the match
method:
export const const area: number
area = const someShape: MatchboxMember<"Circle", {
Circle: (radius: number) => {
radius: number;
};
Square: (side: number) => {
side: number;
};
Rectangle: (width: number, height: number) => {
width: number;
height: number;
};
}, "type">
someShape.MatchboxMemberApi<{ Circle: (radius: number) => { radius: number; }; Square: (side: number) => { side: number; }; Rectangle: (width: number, height: number) => { width: number; height: number; }; }, "type">.match<number>(cases: MatchCases<{
Circle: (radius: number) => {
radius: number;
};
Square: (side: number) => {
side: number;
};
Rectangle: (width: number, height: number) => {
width: number;
height: number;
};
}, number, true>, exhaustive?: boolean): number (+1 overload)
match({
type Circle: ({ radius }: {
radius: number;
}) => number
Circle: ({ radius: number
radius }) => var Math: Math
An intrinsic object that provides basic mathematics functionality and constants.Math.Math.PI: number
Pi. This is the ratio of the circumference of a circle to its diameter.PI * radius: number
radius * radius: number
radius,
type Square: ({ side }: {
side: number;
}) => number
Square: ({ side: number
side }) => side: number
side * side: number
side,
type Rectangle: ({ width, height }: {
width: number;
height: number;
}) => number
Rectangle: ({ width: number
width, height: number
height }) => width: number
width * height: number
height,
});
Using Default Cases
Section titled “Using Default Cases”Sometimes you want to handle multiple states with a single case, or provide a fallback:
export const const cornerCount: number
cornerCount = const someShape: MatchboxMember<"Circle", {
Circle: (radius: number) => {
radius: number;
};
Square: (side: number) => {
side: number;
};
Rectangle: (width: number, height: number) => {
width: number;
height: number;
};
}, "type">
someShape.MatchboxMemberApi<{ Circle: (radius: number) => { radius: number; }; Square: (side: number) => { side: number; }; Rectangle: (width: number, height: number) => { width: number; height: number; }; }, "type">.match<number>(cases: MatchCases<{
Circle: (radius: number) => {
radius: number;
};
Square: (side: number) => {
side: number;
};
Rectangle: (width: number, height: number) => {
width: number;
height: number;
};
}, number, true>, exhaustive?: boolean): number (+1 overload)
match({
type Circle: () => number
Circle: () => 0,
_?: ((...args: any[]) => number) | undefined
_: () => 4, // Default case for Square and Rectangle
});
Non-Exhaustive Matching
Section titled “Non-Exhaustive Matching”You can opt-out of exhaustiveness checking by passing false
as the second argument:
export const const optionalNickname: string
optionalNickname = const someShape: MatchboxMember<"Circle", {
Circle: (radius: number) => {
radius: number;
};
Square: (side: number) => {
side: number;
};
Rectangle: (width: number, height: number) => {
width: number;
height: number;
};
}, "type">
someShape.MatchboxMemberApi<{ Circle: (radius: number) => { radius: number; }; Square: (side: number) => { side: number; }; Rectangle: (width: number, height: number) => { width: number; height: number; }; }, "type">.match<string>(cases: MatchCases<{
Circle: (radius: number) => {
radius: number;
};
Square: (side: number) => {
side: number;
};
Rectangle: (width: number, height: number) => {
width: number;
height: number;
};
}, string, true>, exhaustive?: boolean): string (+1 overload)
match(
{
type Circle: ({ radius }: {
radius: number;
}) => string
Circle: ({ radius: number
radius }) => `Circle with radius ${radius: number
radius}`,
type Square: ({ side }: {
side: number;
}) => string
Square: ({ side: number
side }) => `Square with side ${side: number
side}`,
},
false
);