Skip to content

Matchbox Usage

One of the most powerful features of Matchbox is exhaustive pattern matching with the match method, serving as an alternative to switch statements that are not guaranteed to be exhaustive.

Given the following matchbox factory:

export const shapes = matchboxFactory({
Circle: (radius: number) => ({ radius }),
Square: (side: number) => ({ side }),
Rectangle: (width: number, height: number) => ({ width, height }),
});

The most powerful feature of tagged unions created with matchboxFactory is exhaustive pattern matching with the match method:

export const const area: numberarea = 
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: numberradius }) => 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: numberradius * radius: numberradius,
type Square: ({ side }: {
    side: number;
}) => number
Square
: ({ side: numberside }) => side: numberside * side: numberside,
type Rectangle: ({ width, height }: {
    width: number;
    height: number;
}) => number
Rectangle
: ({ width: numberwidth, height: numberheight }) => width: numberwidth * height: numberheight,
});

Sometimes you want to handle multiple states with a single case, or provide a fallback:

export const const cornerCount: numbercornerCount = 
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: () => numberCircle: () => 0, _?: ((...args: any[]) => number) | undefined_: () => 4, // Default case for Square and Rectangle });

You can opt-out of exhaustiveness checking by passing false as the second argument:

export const const optionalNickname: stringoptionalNickname = 
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: numberradius }) => `Circle with radius ${radius: numberradius}`,
type Square: ({ side }: {
    side: number;
}) => string
Square
: ({ side: numberside }) => `Square with side ${side: numberside}`,
}, false );

Using type guards in Matchbox provides several benefits:

  • Type safety: Prevent runtime errors by catching type mismatches at compile time
  • Code completion: Get proper IDE suggestions based on narrowed types
  • Refactoring safety: When you change a state’s structure, TypeScript will flag all places that need updates
  • Exhaustive checking: Ensure all possible states are handled with pattern matching

Tagged union instances created with matchboxFactory provide automatic type narrowing with the is method:

// Create a Light matchbox with On/Off states
const 
const Light: MatchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
Light
=
matchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag", MatchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">>(config: {
    ...;
}, tagProp?: "tag" | undefined): MatchboxFactory<...>
Create a tagged union from a record mapping tags to value types, along with associated variant constructors, type predicates and `match` function.
@templateConfig - The configuration object or array of tags@templateTagProp - The property name used for the tag (default: "tag")@returnsAn object with constructors for each variant, type predicates, and match function@example```ts // Define a union of variants for a Result type const Result = matchboxFactory({ Ok: (value: number) => ({ value }), Err: (error: string) => ({ error }), }); // Create instances const ok = Result.Ok(42); const err = Result.Err("fail"); // Type predicates ok.is("Ok"); // true err.is("Err"); // true // Pattern matching const message = ok.match({ Ok: ({ value }) => `Value: ${value}`, Err: ({ error }) => `Error: ${error}`, }); // message === "Value: 42" ```
matchboxFactory
({
type Off: undefinedOff: var undefinedundefined,
type On: (percentage?: number) => {
    percentage: number;
}
On
: (percentage: numberpercentage = 100) => ({ percentage: numberpercentage }),
}); // Create light instances const
const light1: MatchboxMember<"Off", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light1
=
const Light: MatchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
Light
.
type Off: () => MatchboxMember<"Off", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
Off
();
const
const light2: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light2
=
const Light: MatchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
Light
.
type On: (percentage?: number | undefined) => MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
On
(75);
// Type guards with automatic type narrowing if (
const light2: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light2
.MatchboxMemberApi<{ Off: undefined; On: (percentage?: number) => { percentage: number; }; }, "tag">.is: <"On">(key: "On") => this is MatchboxMember<T, DataSpecs, TagProp>is("On")) {
// TypeScript knows light2.data has percentage var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstderr). The global `console` can be used without calling `require('console')`. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v20.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v20.11.1/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
(`Brightness: ${
const light2: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light2
.
data: {
    percentage: number;
}
data
.percentage: numberpercentage}%`);
// This would be a TypeScript error: // console.log(light2.data.invalid); // Error: Property 'invalid' does not exist } // Type guards can be used in conditions function function getBrightness(light: ReturnType<typeof Light.Off> | ReturnType<typeof Light.On>): numbergetBrightness(
light: MatchboxMember<"Off", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag"> | MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light
: type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any
Obtain the return type of a function type
ReturnType
<typeof
const Light: MatchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
Light
.
type Off: () => MatchboxMember<"Off", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
Off
> | type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any
Obtain the return type of a function type
ReturnType
<typeof
const Light: MatchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
Light
.
type On: (percentage?: number | undefined) => MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
On
>
) { if (
light: MatchboxMember<"Off", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag"> | MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light
.MatchboxMemberApi<DataSpecs, TagProp extends string>.is: <"Off">(key: "Off") => this is MatchboxMember<T, DataSpecs, TagProp>is("Off")) {
return 0; } // TypeScript knows this must be the "On" state with percentage return
light: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light
.
data: {
    percentage: number;
}
data
.percentage: numberpercentage;
} var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstderr). The global `console` can be used without calling `require('console')`. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v20.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v20.11.1/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
(function getBrightness(light: ReturnType<typeof Light.Off> | ReturnType<typeof Light.On>): numbergetBrightness(
const light1: MatchboxMember<"Off", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light1
)); // 0
var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstderr). The global `console` can be used without calling `require('console')`. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v20.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v20.11.1/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
(function getBrightness(light: ReturnType<typeof Light.Off> | ReturnType<typeof Light.On>): numbergetBrightness(
const light2: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light2
)); // 75

Use the as method for type-safe casting with runtime validation:

import { function matchboxFactory<Config extends TaggedTypes | string, TagProp extends string = "tag", R = MatchboxFactory<Config extends readonly string[] ? { [K in Config[number]]: (data: any) => any; } : Config, TagProp>>(config: Config, tagProp?: TagProp): R
Create a tagged union from a record mapping tags to value types, along with associated variant constructors, type predicates and `match` function.
@templateConfig - The configuration object or array of tags@templateTagProp - The property name used for the tag (default: "tag")@returnsAn object with constructors for each variant, type predicates, and match function@example```ts // Define a union of variants for a Result type const Result = matchboxFactory({ Ok: (value: number) => ({ value }), Err: (error: string) => ({ error }), }); // Create instances const ok = Result.Ok(42); const err = Result.Err("fail"); // Type predicates ok.is("Ok"); // true err.is("Err"); // true // Pattern matching const message = ok.match({ Ok: ({ value }) => `Value: ${value}`, Err: ({ error }) => `Error: ${error}`, }); // message === "Value: 42" ```
matchboxFactory
} from "matchina";
// Create a Light matchbox with On/Off states const
const Light: MatchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
Light
=
matchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag", MatchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">>(config: {
    ...;
}, tagProp?: "tag" | undefined): MatchboxFactory<...>
Create a tagged union from a record mapping tags to value types, along with associated variant constructors, type predicates and `match` function.
@templateConfig - The configuration object or array of tags@templateTagProp - The property name used for the tag (default: "tag")@returnsAn object with constructors for each variant, type predicates, and match function@example```ts // Define a union of variants for a Result type const Result = matchboxFactory({ Ok: (value: number) => ({ value }), Err: (error: string) => ({ error }), }); // Create instances const ok = Result.Ok(42); const err = Result.Err("fail"); // Type predicates ok.is("Ok"); // true err.is("Err"); // true // Pattern matching const message = ok.match({ Ok: ({ value }) => `Value: ${value}`, Err: ({ error }) => `Error: ${error}`, }); // message === "Value: 42" ```
matchboxFactory
({
type Off: undefinedOff: var undefinedundefined,
type On: (percentage?: number) => {
    percentage: number;
}
On
: (percentage: numberpercentage = 100) => ({ percentage: numberpercentage }),
}); const
const light: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light
=
const Light: MatchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
Light
.
type On: (percentage?: number | undefined) => MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
On
(80);
// Safe casting with runtime validation try { // This works because light is actually in the "On" state const
const asOn: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
asOn
=
const light: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light
.
MatchboxMemberApi<{ Off: undefined; On: (percentage?: number) => { percentage: number; }; }, "tag">.as: <"On">(key: "On") => MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
as
("On");
var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstderr). The global `console` can be used without calling `require('console')`. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v20.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v20.11.1/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
(`Brightness: ${
const asOn: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
asOn
.
data: {
    percentage: number;
}
data
.percentage: numberpercentage}%`); // Works fine: "Brightness: 80%"
// This will throw because light is not in the "Off" state const
const asOff: MatchboxMember<"Off", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
asOff
=
const light: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light
.
MatchboxMemberApi<{ Off: undefined; On: (percentage?: number) => { percentage: number; }; }, "tag">.as: <"Off">(key: "Off") => MatchboxMember<"Off", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
as
("Off");
var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstderr). The global `console` can be used without calling `require('console')`. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v20.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v20.11.1/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
("This line will never execute",
const asOff: MatchboxMember<"Off", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
asOff
);
} catch (var e: anye: any) { var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstderr). The global `console` can be used without calling `require('console')`. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v20.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v20.11.1/lib/console.js)
console
.Console.error(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stderr` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args)). ```js const code = 5; console.error('error #%d', code); // Prints: error #5, to stderr console.error('error', code); // Prints: error 5, to stderr ``` If formatting elements (e.g. `%d`) are not found in the first string then [`util.inspect()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilinspectobject-options) is called on each argument and the resulting string values are concatenated. See [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
error
("Cast failed:", var e: anye.message); // "Attempted to cast On as Off"
} // Practical example: only adjust brightness for "On" lights export function
function adjustBrightness(light: ReturnType<typeof Light.Off> | ReturnType<typeof Light.On>, adjustment: number): MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag"> | MatchboxMember<...>
adjustBrightness
(
light: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag"> | MatchboxMember<"Off", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light
: type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any
Obtain the return type of a function type
ReturnType
<typeof
const Light: MatchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
Light
.
type Off: () => MatchboxMember<"Off", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
Off
> | type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any
Obtain the return type of a function type
ReturnType
<typeof
const Light: MatchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
Light
.
type On: (percentage?: number | undefined) => MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
On
>,
adjustment: numberadjustment: number ) { try { // Try to cast to "On" state const
const onLight: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
onLight
=
light: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag"> | MatchboxMember<"Off", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light
.
MatchboxMemberApi<DataSpecs, TagProp extends string>.as: <"On">(key: "On") => MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
as
("On");
// If successful, create a new light with adjusted brightness const const newBrightness: numbernewBrightness = var Math: Math
An intrinsic object that provides basic mathematics functionality and constants.
Math
.Math.max(...values: number[]): number
Returns the larger of a set of supplied numeric expressions.
@paramvalues Numeric expressions to be evaluated.
max
(
0, var Math: Math
An intrinsic object that provides basic mathematics functionality and constants.
Math
.Math.min(...values: number[]): number
Returns the smaller of a set of supplied numeric expressions.
@paramvalues Numeric expressions to be evaluated.
min
(100,
const onLight: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
onLight
.
data: {
    percentage: number;
}
data
.percentage: numberpercentage + adjustment: numberadjustment)
); return
const Light: MatchboxFactory<{
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
Light
.
type On: (percentage?: number | undefined) => MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
On
(const newBrightness: numbernewBrightness);
} catch { // Light is off, return it unchanged return
light: MatchboxMember<"On", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag"> | MatchboxMember<"Off", {
    Off: undefined;
    On: (percentage?: number) => {
        percentage: number;
    };
}, "tag">
light
;
} }

Matchina also provides filter functions for more complex type guards:

import { matchbox, withKey, withData } from "matchina";
// ---cut---
const Shape = matchbox({
Circle: (radius: number, color: string = "black") => ({ radius, color }),
Rectangle: (width: number, height: number, color: string = "black") => ({
width,
height,
color,
}),
Triangle: (base: number, height: number, color: string = "black") => ({
base,
height,
color,
}),
});
const shapes = [
Shape.Circle(5, "red"),
Shape.Rectangle(10, 20, "blue"),
Shape.Circle(8, "green"),
Shape.Triangle(15, 10, "red"),
];
// Filter by key
const circles = shapes.filter(withKey("Circle"));
console.log(`Found ${circles.length} circles`);
// Filter by data property
const redShapes = shapes.filter(withData((data) => data.color === "red"));
console.log(`Found ${redShapes.length} red shapes`);
// Combine filters
const largeCircles = shapes.filter(
(shape) => shape.is("Circle") && shape.data.radius > 7,
);
console.log(`Found ${largeCircles.length} large circles`);

Now that you understand type guards, explore these related guides: