Pattern Matching

When working with Result types that have union error types, pattern matching becomes essential for handling different error scenarios effectively. This guide demonstrates how to use pattern matching to handle multiple error types gracefully.

Why Pattern Matching for Union Errors?

When your Result can fail with multiple different error types, you need a systematic way to handle each error type appropriately. Pattern matching provides a clean, type-safe approach to handle all possible error cases.

Tip

For more details about @praha/error-factory, see the Custom Error page.

import { 
const ErrorFactory: {
    <Name extends string = string, Message extends string = string, Fields extends ErrorFields = ErrorFields>(props: {
        name?: Name;
        message: Message | ((fields: Fields) => Message);
        fields?: Fields;
    }): ErrorConstructor<Name, Message, Fields>;
    fields<Fields extends ErrorFields>(): Fields;
}

A factory function that creates a base class for custom error types.

Extend the returned class to define a custom error with a consistent structure, reducing boilerplate and ensuring type safety across your application.

@typeParamName - Inferred as a string literal type from props.name when provided, or defaults to string when name is omitted.@typeParamMessage - Inferred as a string literal type from props.message when it is a string, or defaults to string when message is a function.@typeParamFields - Inferred from props.fields (via ErrorFactory.fields). Defaults to the base ErrorFields constraint when fields is omitted.@paramprops - Configuration for the error class.@paramprops .name - The value set as the name property on both the class and each instance. When omitted, name is inferred as string and set to new.target.name at construction time, which resolves to the name of the concrete subclass. Note that omitting name disables type narrowing via the name property; use name explicitly or instanceof for narrowing.@paramprops .message - The error message. Can be a static string or a function that receives the custom fields and returns a string, enabling dynamic message generation.@paramprops .fields - A type-level placeholder that declares the additional fields the error instance will carry. Use ErrorFactory.fields to create this value. When omitted, no additional fields are added to the instance.@returnsAn abstract base class typed as ErrorConstructor that should be extended to produce a concrete custom error class.@example

Basic usage

class NotFoundError extends ErrorFactory({
name: 'NotFoundError',
message: 'Resource not found',
}) {}

const error = new NotFoundError();
console.error(error.name);    // "NotFoundError"
console.error(error.message); // "Resource not found"
@example

Omitting name

class NotFoundError extends ErrorFactory({
message: 'Resource not found',
}) {}

const error = new NotFoundError();
console.error(error.name); // "NotFoundError" (resolved from new.target.name)
@example

With cause

class DatabaseError extends ErrorFactory({
name: 'DatabaseError',
message: 'A database error occurred',
}) {}

const error = new DatabaseError({ cause: new Error('Connection failed') });
console.error(error.cause); // Error: Connection failed
@example

With additional fields

class QueryError extends ErrorFactory({
name: 'QueryError',
message: 'An error occurred while executing a query',
fields: ErrorFactory.fields<{ query: string }>(),
}) {}

const error = new QueryError({ query: 'SELECT * FROM users' });
console.error(error.query); // "SELECT * FROM users"
@example

Dynamic message

class ValidationError extends ErrorFactory({
name: 'ValidationError',
message: ({ field }) => `Validation failed for field '${field}'`,
fields: ErrorFactory.fields<{ field: string }>(),
}) {}

const error = new ValidationError({ field: 'email' });
console.error(error.message); // "Validation failed for field 'email'"
ErrorFactory
} from '@praha/error-factory';
import {
import Result
Result
} from '@praha/byethrow';
class
class PostNotFoundError
PostNotFoundError
extends
ErrorFactory<"PostNotFoundError", "The requested post was not found.", ErrorFields>(props: {
    name?: "PostNotFoundError" | undefined;
    message: "The requested post was not found." | ((fields: ErrorFields) => "The requested post was not found.");
    fields?: ErrorFields | undefined;
}): (new (options?: ErrorOptions) => Error & Readonly<{
    name: "PostNotFoundError";
    message: "The requested post was not found.";
}>) & {
    name: "PostNotFoundError";
}

A factory function that creates a base class for custom error types.

Extend the returned class to define a custom error with a consistent structure, reducing boilerplate and ensuring type safety across your application.

@typeParamName - Inferred as a string literal type from props.name when provided, or defaults to string when name is omitted.@typeParamMessage - Inferred as a string literal type from props.message when it is a string, or defaults to string when message is a function.@typeParamFields - Inferred from props.fields (via ErrorFactory.fields). Defaults to the base ErrorFields constraint when fields is omitted.@paramprops - Configuration for the error class.@paramprops .name - The value set as the name property on both the class and each instance. When omitted, name is inferred as string and set to new.target.name at construction time, which resolves to the name of the concrete subclass. Note that omitting name disables type narrowing via the name property; use name explicitly or instanceof for narrowing.@paramprops .message - The error message. Can be a static string or a function that receives the custom fields and returns a string, enabling dynamic message generation.@paramprops .fields - A type-level placeholder that declares the additional fields the error instance will carry. Use ErrorFactory.fields to create this value. When omitted, no additional fields are added to the instance.@returnsAn abstract base class typed as ErrorConstructor that should be extended to produce a concrete custom error class.@example

Basic usage

class NotFoundError extends ErrorFactory({
name: 'NotFoundError',
message: 'Resource not found',
}) {}

const error = new NotFoundError();
console.error(error.name);    // "NotFoundError"
console.error(error.message); // "Resource not found"
@example

Omitting name

class NotFoundError extends ErrorFactory({
message: 'Resource not found',
}) {}

const error = new NotFoundError();
console.error(error.name); // "NotFoundError" (resolved from new.target.name)
@example

With cause

class DatabaseError extends ErrorFactory({
name: 'DatabaseError',
message: 'A database error occurred',
}) {}

const error = new DatabaseError({ cause: new Error('Connection failed') });
console.error(error.cause); // Error: Connection failed
@example

With additional fields

class QueryError extends ErrorFactory({
name: 'QueryError',
message: 'An error occurred while executing a query',
fields: ErrorFactory.fields<{ query: string }>(),
}) {}

const error = new QueryError({ query: 'SELECT * FROM users' });
console.error(error.query); // "SELECT * FROM users"
@example

Dynamic message

class ValidationError extends ErrorFactory({
name: 'ValidationError',
message: ({ field }) => `Validation failed for field '${field}'`,
fields: ErrorFactory.fields<{ field: string }>(),
}) {}

const error = new ValidationError({ field: 'email' });
console.error(error.message); // "Validation failed for field 'email'"
ErrorFactory
({
name?: "PostNotFoundError" | undefined
name
: 'PostNotFoundError',
message: "The requested post was not found." | ((fields: ErrorFields) => "The requested post was not found.")
message
: 'The requested post was not found.',
}) {} class
class PostPermissionError
PostPermissionError
extends
ErrorFactory<"PostPermissionError", "You do not have permission to perform this action.", ErrorFields>(props: {
    name?: "PostPermissionError" | undefined;
    message: "You do not have permission to perform this action." | ((fields: ErrorFields) => "You do not have permission to perform this action.");
    fields?: ErrorFields | undefined;
}): (new (options?: ErrorOptions) => Error & Readonly<{
    name: "PostPermissionError";
    message: "You do not have permission to perform this action.";
}>) & {
    name: "PostPermissionError";
}

A factory function that creates a base class for custom error types.

Extend the returned class to define a custom error with a consistent structure, reducing boilerplate and ensuring type safety across your application.

@typeParamName - Inferred as a string literal type from props.name when provided, or defaults to string when name is omitted.@typeParamMessage - Inferred as a string literal type from props.message when it is a string, or defaults to string when message is a function.@typeParamFields - Inferred from props.fields (via ErrorFactory.fields). Defaults to the base ErrorFields constraint when fields is omitted.@paramprops - Configuration for the error class.@paramprops .name - The value set as the name property on both the class and each instance. When omitted, name is inferred as string and set to new.target.name at construction time, which resolves to the name of the concrete subclass. Note that omitting name disables type narrowing via the name property; use name explicitly or instanceof for narrowing.@paramprops .message - The error message. Can be a static string or a function that receives the custom fields and returns a string, enabling dynamic message generation.@paramprops .fields - A type-level placeholder that declares the additional fields the error instance will carry. Use ErrorFactory.fields to create this value. When omitted, no additional fields are added to the instance.@returnsAn abstract base class typed as ErrorConstructor that should be extended to produce a concrete custom error class.@example

Basic usage

class NotFoundError extends ErrorFactory({
name: 'NotFoundError',
message: 'Resource not found',
}) {}

const error = new NotFoundError();
console.error(error.name);    // "NotFoundError"
console.error(error.message); // "Resource not found"
@example

Omitting name

class NotFoundError extends ErrorFactory({
message: 'Resource not found',
}) {}

const error = new NotFoundError();
console.error(error.name); // "NotFoundError" (resolved from new.target.name)
@example

With cause

class DatabaseError extends ErrorFactory({
name: 'DatabaseError',
message: 'A database error occurred',
}) {}

const error = new DatabaseError({ cause: new Error('Connection failed') });
console.error(error.cause); // Error: Connection failed
@example

With additional fields

class QueryError extends ErrorFactory({
name: 'QueryError',
message: 'An error occurred while executing a query',
fields: ErrorFactory.fields<{ query: string }>(),
}) {}

const error = new QueryError({ query: 'SELECT * FROM users' });
console.error(error.query); // "SELECT * FROM users"
@example

Dynamic message

class ValidationError extends ErrorFactory({
name: 'ValidationError',
message: ({ field }) => `Validation failed for field '${field}'`,
fields: ErrorFactory.fields<{ field: string }>(),
}) {}

const error = new ValidationError({ field: 'email' });
console.error(error.message); // "Validation failed for field 'email'"
ErrorFactory
({
name?: "PostPermissionError" | undefined
name
: 'PostPermissionError',
message: "You do not have permission to perform this action." | ((fields: ErrorFields) => "You do not have permission to perform this action.")
message
: 'You do not have permission to perform this action.',
}) {} class
class PostAlreadyDeletedError
PostAlreadyDeletedError
extends
ErrorFactory<"PostAlreadyDeletedError", "This post has already been deleted.", ErrorFields>(props: {
    name?: "PostAlreadyDeletedError" | undefined;
    message: "This post has already been deleted." | ((fields: ErrorFields) => "This post has already been deleted.");
    fields?: ErrorFields | undefined;
}): (new (options?: ErrorOptions) => Error & Readonly<{
    name: "PostAlreadyDeletedError";
    message: "This post has already been deleted.";
}>) & {
    name: "PostAlreadyDeletedError";
}

A factory function that creates a base class for custom error types.

Extend the returned class to define a custom error with a consistent structure, reducing boilerplate and ensuring type safety across your application.

@typeParamName - Inferred as a string literal type from props.name when provided, or defaults to string when name is omitted.@typeParamMessage - Inferred as a string literal type from props.message when it is a string, or defaults to string when message is a function.@typeParamFields - Inferred from props.fields (via ErrorFactory.fields). Defaults to the base ErrorFields constraint when fields is omitted.@paramprops - Configuration for the error class.@paramprops .name - The value set as the name property on both the class and each instance. When omitted, name is inferred as string and set to new.target.name at construction time, which resolves to the name of the concrete subclass. Note that omitting name disables type narrowing via the name property; use name explicitly or instanceof for narrowing.@paramprops .message - The error message. Can be a static string or a function that receives the custom fields and returns a string, enabling dynamic message generation.@paramprops .fields - A type-level placeholder that declares the additional fields the error instance will carry. Use ErrorFactory.fields to create this value. When omitted, no additional fields are added to the instance.@returnsAn abstract base class typed as ErrorConstructor that should be extended to produce a concrete custom error class.@example

Basic usage

class NotFoundError extends ErrorFactory({
name: 'NotFoundError',
message: 'Resource not found',
}) {}

const error = new NotFoundError();
console.error(error.name);    // "NotFoundError"
console.error(error.message); // "Resource not found"
@example

Omitting name

class NotFoundError extends ErrorFactory({
message: 'Resource not found',
}) {}

const error = new NotFoundError();
console.error(error.name); // "NotFoundError" (resolved from new.target.name)
@example

With cause

class DatabaseError extends ErrorFactory({
name: 'DatabaseError',
message: 'A database error occurred',
}) {}

const error = new DatabaseError({ cause: new Error('Connection failed') });
console.error(error.cause); // Error: Connection failed
@example

With additional fields

class QueryError extends ErrorFactory({
name: 'QueryError',
message: 'An error occurred while executing a query',
fields: ErrorFactory.fields<{ query: string }>(),
}) {}

const error = new QueryError({ query: 'SELECT * FROM users' });
console.error(error.query); // "SELECT * FROM users"
@example

Dynamic message

class ValidationError extends ErrorFactory({
name: 'ValidationError',
message: ({ field }) => `Validation failed for field '${field}'`,
fields: ErrorFactory.fields<{ field: string }>(),
}) {}

const error = new ValidationError({ field: 'email' });
console.error(error.message); // "Validation failed for field 'email'"
ErrorFactory
({
name?: "PostAlreadyDeletedError" | undefined
name
: 'PostAlreadyDeletedError',
message: "This post has already been deleted." | ((fields: ErrorFields) => "This post has already been deleted.")
message
: 'This post has already been deleted.',
}) {} // Example of a post deletion function type
type PostDeleteError = PostNotFoundError | PostPermissionError | PostAlreadyDeletedError
PostDeleteError
= (
|
class PostNotFoundError
PostNotFoundError
|
class PostPermissionError
PostPermissionError
|
class PostAlreadyDeletedError
PostAlreadyDeletedError
); // Function that can return multiple error types const
const deletePost: (postId: string) => Result.ResultAsync<void, PostDeleteError>
deletePost
= async (
postId: string
postId
: string):
import Result
Result
.
type ResultAsync<T, E> = Promise<Result.Result<T, E>>

An asynchronous variant of Result , wrapped in a Promise.

@typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@example
import { Result } from '@praha/byethrow';

const fetchData = async (): Result.ResultAsync<string, Error> => {
  try {
    const data = await fetch('...');
    return { type: 'Success', value: await data.text() };
  } catch (err) {
    return { type: 'Failure', error: err as Error };
  }
};
@categoryCore Types
ResultAsync
<void,
type PostDeleteError = PostNotFoundError | PostPermissionError | PostAlreadyDeletedError
PostDeleteError
> => {
// Implementation that can return any of the error types }; // Handling the result with pattern matching await
import Result
Result
.
const pipe: <Result.ResultAsync<void, PostDeleteError>, Result.ResultAsync<string, PostDeleteError>, Result.ResultAsync<string, PostDeleteError>>(a: Result.ResultAsync<void, PostDeleteError>, ab: (a: Result.ResultAsync<void, PostDeleteError>) => Result.ResultAsync<string, PostDeleteError>, bc: (b: Result.ResultAsync<string, PostDeleteError>) => Result.ResultAsync<string, PostDeleteError>) => Result.ResultAsync<...> (+25 overloads)
pipe
(
const deletePost: (postId: string) => Result.ResultAsync<void, PostDeleteError>
deletePost
('123'),
import Result
Result
.
const map: <Result.ResultAsync<void, PostDeleteError>, string>(fn: (a: void) => string) => (result: Result.ResultAsync<void, PostDeleteError>) => Result.ResultAsync<string, PostDeleteError> (+1 overload)
map
(() => 'Post deleted successfully!'),
import Result
Result
.
const inspectError: <Result.ResultAsync<string, PostDeleteError>, void>(fn: (a: PostDeleteError) => void) => (result: Result.ResultAsync<string, PostDeleteError>) => Result.ResultAsync<string, PostDeleteError> (+1 overload)
inspectError
((
error: PostDeleteError
error
) => {
// Pattern matching to handle different error types }), );

We strongly recommend using the ts-pattern for pattern matching. It provides excellent TypeScript support and ensures exhaustive matching.

Installation

npm
yarn
pnpm
bun
deno
npm install ts-pattern

Pattern Matching with ts-pattern

import { 
import Result
Result
} from '@praha/byethrow';
import {
function match<const input, output = typeof unset>(value: input): Match<input, output>

match creates a pattern matching expression.

  • Use .with(pattern, handler) to pattern match on the input.
  • Use .exhaustive() or .otherwise(() => defaultValue) to end the expression and get the result.

Read the documentation for match on GitHub

@example

declare let input: "A" | "B";

return match(input) .with("A", () => "It's an A!") .with("B", () => "It's a B!") .exhaustive();

match
} from 'ts-pattern';
await
import Result
Result
.
const pipe: <Result.ResultAsync<void, PostDeleteError>, Result.ResultAsync<void, PostDeleteError>>(a: Result.ResultAsync<void, PostDeleteError>, ab: (a: Result.ResultAsync<void, PostDeleteError>) => Result.ResultAsync<void, PostDeleteError>) => Result.ResultAsync<void, PostDeleteError> (+25 overloads)
pipe
(
function deletePost(postId: string): Result.ResultAsync<void, PostDeleteError>
deletePost
('123'),
import Result
Result
.
const inspectError: <Result.ResultAsync<void, PostDeleteError>, void>(fn: (a: PostDeleteError) => void) => (result: Result.ResultAsync<void, PostDeleteError>) => Result.ResultAsync<void, PostDeleteError> (+1 overload)
inspectError
((
error: PostDeleteError
error
) => {
match<PostDeleteError, typeof unset>(value: PostDeleteError): Match<PostDeleteError, typeof unset>

match creates a pattern matching expression.

  • Use .with(pattern, handler) to pattern match on the input.
  • Use .exhaustive() or .otherwise(() => defaultValue) to end the expression and get the result.

Read the documentation for match on GitHub

@example

declare let input: "A" | "B";

return match(input) .with("A", () => "It's an A!") .with("B", () => "It's a B!") .exhaustive();

match
(
error: PostDeleteError
error
)
.
with<{
    readonly name: "PostNotFoundError";
}, void, PostNotFoundError>(pattern: {
    readonly name: "PostNotFoundError";
}, handler: (selections: PostNotFoundError, value: PostNotFoundError) => void): Match<PostPermissionError | PostAlreadyDeletedError, typeof unset, [{
    readonly name: "PostNotFoundError";
}], void> (+3 overloads)

.with(pattern, handler) Registers a pattern and an handler function that will be called if the pattern matches the input value.

Read the documentation for .with() on GitHub

with
({
name: "PostNotFoundError"
name
: 'PostNotFoundError' }, () => {
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 and process.stderr. The global console can be used without importing the node:console module.

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 for more information.

Example using the global console:

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:

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
@seesource
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) (the arguments are all passed to util.format()).

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() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0 .1.100
error
('The requested post was not found.');
}) .
with<{
    readonly name: "PostPermissionError";
}, void, PostPermissionError>(pattern: {
    readonly name: "PostPermissionError";
}, handler: (selections: PostPermissionError, value: PostPermissionError) => void): Match<PostAlreadyDeletedError, typeof unset, [{
    readonly name: "PostNotFoundError";
}, {
    readonly name: "PostPermissionError";
}], void> (+3 overloads)

.with(pattern, handler) Registers a pattern and an handler function that will be called if the pattern matches the input value.

Read the documentation for .with() on GitHub

with
({
name: "PostPermissionError"
name
: 'PostPermissionError' }, () => {
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 and process.stderr. The global console can be used without importing the node:console module.

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 for more information.

Example using the global console:

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:

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
@seesource
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) (the arguments are all passed to util.format()).

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() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0 .1.100
error
('You do not have permission to perform this action.');
}) .
with<{
    readonly name: "PostAlreadyDeletedError";
}, void, PostAlreadyDeletedError>(pattern: {
    readonly name: "PostAlreadyDeletedError";
}, handler: (selections: PostAlreadyDeletedError, value: PostAlreadyDeletedError) => void): Match<never, typeof unset, [{
    readonly name: "PostNotFoundError";
}, {
    readonly name: "PostPermissionError";
}, {
    readonly name: "PostAlreadyDeletedError";
}], void> (+3 overloads)

.with(pattern, handler) Registers a pattern and an handler function that will be called if the pattern matches the input value.

Read the documentation for .with() on GitHub

with
({
name: "PostAlreadyDeletedError"
name
: 'PostAlreadyDeletedError' }, () => {
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 and process.stderr. The global console can be used without importing the node:console module.

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 for more information.

Example using the global console:

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:

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
@seesource
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) (the arguments are all passed to util.format()).

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() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0 .1.100
error
('This post has already been deleted.');
}) .
exhaustive: () => void (+1 overload)

.exhaustive() checks that all cases are handled, and returns the result value.

If you get a NonExhaustiveError, it means that you aren't handling all cases. You should probably add another .with(...) clause to match the missing case and prevent runtime errors.

Read the documentation for .exhaustive() on GitHub

exhaustive
(); // Ensures all cases are handled
}), );

Alternative: Native TypeScript Pattern Matching

If you prefer not to use external libraries, you can implement pattern matching using TypeScript's built-in features:

Using instanceof Checks

import { 
import Result
Result
} from '@praha/byethrow';
await
import Result
Result
.
const pipe: <Result.ResultAsync<void, PostDeleteError>, Result.ResultAsync<void, PostDeleteError>>(a: Result.ResultAsync<void, PostDeleteError>, ab: (a: Result.ResultAsync<void, PostDeleteError>) => Result.ResultAsync<void, PostDeleteError>) => Result.ResultAsync<void, PostDeleteError> (+25 overloads)
pipe
(
function deletePost(postId: string): Result.ResultAsync<void, PostDeleteError>
deletePost
('123'),
import Result
Result
.
const inspectError: <Result.ResultAsync<void, PostDeleteError>, void>(fn: (a: PostDeleteError) => void) => (result: Result.ResultAsync<void, PostDeleteError>) => Result.ResultAsync<void, PostDeleteError> (+1 overload)
inspectError
((
error: PostDeleteError
error
) => {
if (
error: PostDeleteError
error
instanceof
class PostNotFoundError
PostNotFoundError
) {
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 and process.stderr. The global console can be used without importing the node:console module.

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 for more information.

Example using the global console:

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:

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
@seesource
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) (the arguments are all passed to util.format()).

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() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0 .1.100
error
('The requested post was not found.');
} if (
error: PostDeleteError
error
instanceof
class PostPermissionError
PostPermissionError
) {
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 and process.stderr. The global console can be used without importing the node:console module.

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 for more information.

Example using the global console:

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:

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
@seesource
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) (the arguments are all passed to util.format()).

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() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0 .1.100
error
('You do not have permission to perform this action.');
} if (
error: PostDeleteError
error
instanceof
class PostAlreadyDeletedError
PostAlreadyDeletedError
) {
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 and process.stderr. The global console can be used without importing the node:console module.

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 for more information.

Example using the global console:

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:

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
@seesource
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) (the arguments are all passed to util.format()).

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() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0 .1.100
error
('This post has already been deleted.');
} }), );

Using Discriminated Unions

import { 
import Result
Result
} from '@praha/byethrow';
await
import Result
Result
.
const pipe: <Result.ResultAsync<void, PostDeleteError>, Result.ResultAsync<void, PostDeleteError>>(a: Result.ResultAsync<void, PostDeleteError>, ab: (a: Result.ResultAsync<void, PostDeleteError>) => Result.ResultAsync<void, PostDeleteError>) => Result.ResultAsync<void, PostDeleteError> (+25 overloads)
pipe
(
function deletePost(postId: string): Result.ResultAsync<void, PostDeleteError>
deletePost
('123'),
import Result
Result
.
const inspectError: <Result.ResultAsync<void, PostDeleteError>, void>(fn: (a: PostDeleteError) => void) => (result: Result.ResultAsync<void, PostDeleteError>) => Result.ResultAsync<void, PostDeleteError> (+1 overload)
inspectError
((
error: PostDeleteError
error
) => {
switch (
error: PostDeleteError
error
.
Error.name: "PostNotFoundError" | "PostPermissionError" | "PostAlreadyDeletedError"
name
) {
case 'PostNotFoundError':
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 and process.stderr. The global console can be used without importing the node:console module.

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 for more information.

Example using the global console:

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:

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
@seesource
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) (the arguments are all passed to util.format()).

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() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0 .1.100
error
('The requested post was not found.');
break; case 'PostPermissionError':
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 and process.stderr. The global console can be used without importing the node:console module.

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 for more information.

Example using the global console:

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:

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
@seesource
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) (the arguments are all passed to util.format()).

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() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0 .1.100
error
('You do not have permission to perform this action.');
break; case 'PostAlreadyDeletedError':
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 and process.stderr. The global console can be used without importing the node:console module.

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 for more information.

Example using the global console:

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:

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
@seesource
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) (the arguments are all passed to util.format()).

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() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

@sincev0 .1.100
error
('This post has already been deleted.');
break; default: // This should never happen if all error types are covered const
const _exhaustiveCheck: never
_exhaustiveCheck
: never =
error: never
error
;
throw new
var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error
(`Unhandled error type: ${
var JSON: JSON

An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.

JSON
.
JSON.stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string (+1 overload)

Converts a JavaScript value to a JavaScript Object Notation (JSON) string.

@paramvalue A JavaScript value, usually an object or array, to be converted.@paramreplacer A function that transforms the results.@paramspace Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.@throws{TypeError} If a circular reference or a BigInt value is found.
stringify
(
const _exhaustiveCheck: never
_exhaustiveCheck
)}`);
} }), );