• 日本語
  • パターンマッチング

    複数の異なるエラー型を持つ Result 型を扱う際、異なるエラーシナリオを効果的に処理するためにパターンマッチングは不可欠です。 このガイドでは、複数のエラー型を適切に処理するためのパターンマッチングの使い方を示します。

    なぜユニオンエラーにパターンマッチングが必要なのか?

    Result が複数の異なるエラー型で失敗する可能性がある場合、各エラー型を適切に処理する体系的な方法が必要です。 パターンマッチングは、すべての可能なエラーケースを処理するためのクリーンで型安全なアプローチを提供します。

    Tip

    @praha/error-factory の詳細については、Custom Errorページを参照してください。

    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.',
    }) {} // 投稿削除関数の例 type
    type PostDeleteError = PostNotFoundError | PostPermissionError | PostAlreadyDeletedError
    PostDeleteError
    = (
    |
    class PostNotFoundError
    PostNotFoundError
    |
    class PostPermissionError
    PostPermissionError
    |
    class PostAlreadyDeletedError
    PostAlreadyDeletedError
    ); // 複数のエラー型を返す可能性がある関数 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
    > => {
    // いずれかのエラー型を返す可能性のある実装 }; // パターンマッチングによる結果のハンドリング await
    import Result
    Result
    .
    const pipe: <Result.ResultAsync<void, PostDeleteError>, Result.ResultAsync<"Post deleted successfully!", PostDeleteError>, Result.ResultAsync<"Post deleted successfully!", PostDeleteError>>(a: Result.ResultAsync<void, PostDeleteError>, ab: (a: Result.ResultAsync<void, PostDeleteError>) => Result.ResultAsync<"Post deleted successfully!", PostDeleteError>, bc: (b: Result.ResultAsync<"Post deleted successfully!", PostDeleteError>) => Result.ResultAsync<...>) => Result.ResultAsync<...> (+25 overloads)
    pipe
    (
    const deletePost: (postId: string) => Result.ResultAsync<void, PostDeleteError>
    deletePost
    ('123'),
    import Result
    Result
    .
    const map: <Result.ResultAsync<void, PostDeleteError>, "Post deleted successfully!">(fn: (a: void) => "Post deleted successfully!") => (result: Result.ResultAsync<void, PostDeleteError>) => Result.ResultAsync<"Post deleted successfully!", PostDeleteError> (+1 overload)
    map
    (() => 'Post deleted successfully!'),
    import Result
    Result
    .
    const inspectError: <Result.ResultAsync<"Post deleted successfully!", PostDeleteError>, void>(fn: (a: PostDeleteError) => void) => (result: Result.ResultAsync<"Post deleted successfully!", PostDeleteError>) => Result.ResultAsync<"Post deleted successfully!", PostDeleteError> (+1 overload)
    inspectError
    ((
    error: PostDeleteError
    error
    ) => {
    // 異なるエラー型を処理するためのパターンマッチング }), );

    推奨:ts-pattern を使用する

    パターンマッチングにはts-patternの使用を強くお勧めします。 優れたTypeScriptサポートを提供し、網羅的なマッチングを保証します。

    インストール

    npm
    yarn
    pnpm
    bun
    deno
    npm install ts-pattern

    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
    console
    .
    Console.error(...data: any[]): void

    The console.error() static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.

    MDN Reference

    error
    ('リクエストされた投稿が見つかりませんでした。');
    }) .
    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
    console
    .
    Console.error(...data: any[]): void

    The console.error() static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.

    MDN Reference

    error
    ('このアクションを実行する権限がありません。');
    }) .
    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
    console
    .
    Console.error(...data: any[]): void

    The console.error() static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.

    MDN Reference

    error
    ('この投稿は既に削除されています。');
    }) .
    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
    (); // すべてのケースが処理されることを保証する
    }), );

    代替案:TypeScriptネイティブなパターンマッチング

    外部ライブラリを使用したくない場合は、TypeScriptの組み込み機能を使用してパターンマッチングを実装できます。

    instanceof を使用する

    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
    console
    .
    Console.error(...data: any[]): void

    The console.error() static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.

    MDN Reference

    error
    ('リクエストされた投稿が見つかりませんでした。');
    } if (
    error: PostDeleteError
    error
    instanceof
    class PostPermissionError
    PostPermissionError
    ) {
    var console: Console
    console
    .
    Console.error(...data: any[]): void

    The console.error() static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.

    MDN Reference

    error
    ('このアクションを実行する権限がありません。');
    } if (
    error: PostDeleteError
    error
    instanceof
    class PostAlreadyDeletedError
    PostAlreadyDeletedError
    ) {
    var console: Console
    console
    .
    Console.error(...data: any[]): void

    The console.error() static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.

    MDN Reference

    error
    ('この投稿は既に削除されています。');
    } }), );

    判別可能なユニオンを使用する

    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
    console
    .
    Console.error(...data: any[]): void

    The console.error() static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.

    MDN Reference

    error
    ('リクエストされた投稿が見つかりませんでした。');
    break; case 'PostPermissionError':
    var console: Console
    console
    .
    Console.error(...data: any[]): void

    The console.error() static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.

    MDN Reference

    error
    ('このアクションを実行する権限がありません。');
    break; case 'PostAlreadyDeletedError':
    var console: Console
    console
    .
    Console.error(...data: any[]): void

    The console.error() static method outputs a message to the console at the "error" log level. The message is only displayed to the user if the console is configured to display error output. In most cases, the log level is configured within the console UI. The message may be formatted as an error, with red colors and call stack information.

    MDN Reference

    error
    ('この投稿は既に削除されています。');
    break; default: // すべてのエラー型がカバーされていれば、ここには到達しないはず 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
    )}`);
    } }), );