Result を集約する

組み合わせる必要がある複数の Result がある場合、sequencecollect が役立ちます。 どちらも Result を集約しますが、失敗の処理方法が異なります。

sequence - 最初の失敗で停止

sequence はResultを処理し、最初の失敗で停止します。

import { 
import Result
Result
} from '@praha/byethrow';
// すべて成功 const
const success: Result.Result<[1, 2, 3], never>
success
=
import Result
Result
.
const sequence: <[Result.Result<1, never>, Result.Result<2, never>, Result.Result<3, never>]>(x: [Result.Result<1, never>, Result.Result<2, never>, Result.Result<3, never>]) => Result.Result<[1, 2, 3], never> (+4 overloads)
sequence
([
import Result
Result
.
const succeed: <1>(value: 1) => Result.Result<1, never> (+1 overload)
succeed
(1),
import Result
Result
.
const succeed: <2>(value: 2) => Result.Result<2, never> (+1 overload)
succeed
(2),
import Result
Result
.
const succeed: <3>(value: 3) => Result.Result<3, never> (+1 overload)
succeed
(3),
]); // { type: 'Success', value: [1, 2, 3] } // 1つが失敗 - 即座に停止 const
const failure: Result.Result<[1, never, 3], "error">
failure
=
import Result
Result
.
const sequence: <[Result.Result<1, never>, Result.Result<never, "error">, Result.Result<3, never>]>(x: [Result.Result<1, never>, Result.Result<never, "error">, Result.Result<3, never>]) => Result.Result<[1, never, 3], "error"> (+4 overloads)
sequence
([
import Result
Result
.
const succeed: <1>(value: 1) => Result.Result<1, never> (+1 overload)
succeed
(1),
import Result
Result
.
const fail: <"error">(error: "error") => Result.Result<never, "error"> (+1 overload)
fail
('error'),
import Result
Result
.
const succeed: <3>(value: 3) => Result.Result<3, never> (+1 overload)
succeed
(3), // 遅延モードでは評価されない
]); // { type: 'Failure', error: 'error' }

オブジェクトでの使用

import { 
import Result
Result
} from '@praha/byethrow';
// すべて成功 const
const success: Result.Result<{
    name: "Alice";
    age: 30;
    email: "alice@example.com";
}, never>
success
=
import Result
Result
.
const sequence: <{
    name: Result.Result<"Alice", never>;
    age: Result.Result<30, never>;
    email: Result.Result<"alice@example.com", never>;
}>(x: {
    name: Result.Result<"Alice", never>;
    age: Result.Result<30, never>;
    email: Result.Result<"alice@example.com", never>;
}) => Result.Result<{
    name: "Alice";
    age: 30;
    email: "alice@example.com";
}, never> (+4 overloads)
sequence
({
name: Result.Result<"Alice", never>
name
:
import Result
Result
.
const succeed: <"Alice">(value: "Alice") => Result.Result<"Alice", never> (+1 overload)
succeed
('Alice'),
age: Result.Result<30, never>
age
:
import Result
Result
.
const succeed: <30>(value: 30) => Result.Result<30, never> (+1 overload)
succeed
(30),
email: Result.Result<"alice@example.com", never>
email
:
import Result
Result
.
const succeed: <"alice@example.com">(value: "alice@example.com") => Result.Result<"alice@example.com", never> (+1 overload)
succeed
('alice@example.com'),
}); // { type: 'Success', value: { name: 'Alice', age: 30, email: 'alice@example.com' } } // 1つが失敗 - 即座に停止 const
const result: Result.Result<{
    name: "Alice";
    age: never;
    email: "alice@example.com";
}, "error">
result
=
import Result
Result
.
const sequence: <{
    name: Result.Result<"Alice", never>;
    age: Result.Result<never, "error">;
    email: Result.Result<"alice@example.com", never>;
}>(x: {
    name: Result.Result<"Alice", never>;
    age: Result.Result<never, "error">;
    email: Result.Result<"alice@example.com", never>;
}) => Result.Result<{
    name: "Alice";
    age: never;
    email: "alice@example.com";
}, "error"> (+4 overloads)
sequence
({
name: Result.Result<"Alice", never>
name
:
import Result
Result
.
const succeed: <"Alice">(value: "Alice") => Result.Result<"Alice", never> (+1 overload)
succeed
('Alice'),
age: Result.Result<never, "error">
age
:
import Result
Result
.
const fail: <"error">(error: "error") => Result.Result<never, "error"> (+1 overload)
fail
('error'),
email: Result.Result<"alice@example.com", never>
email
:
import Result
Result
.
const succeed: <"alice@example.com">(value: "alice@example.com") => Result.Result<"alice@example.com", never> (+1 overload)
succeed
('alice@example.com'), // 遅延モードでは評価されない
}); // { type: 'Failure', error: 'error' }

例:購入処理パイプライン

一般的なユースケースは、複数の独立した操作がすべて成功する必要がある購入フローです。 sequence では、いずれかのステップが失敗すると、残りの操作はスキップされます。

import { 
import Result
Result
} from '@praha/byethrow';
const
const processPurchase: (user: User, product: Product) => Result.ResultAsync<{
    stock: Stock;
    order: Order;
    confirmation: Confirmation;
}, "OutOfStock" | "OrderFailed" | "EmailFailed">
processPurchase
= (
user: User
user
:
type User = {
    id: string;
    email: string;
}
User
,
product: Product
product
:
type Product = {
    id: string;
    name: string;
}
Product
) => {
return
import Result
Result
.
const sequence: <{
    stock: Result.ResultAsync<Stock, "OutOfStock">;
    order: Result.ResultAsync<Order, "OrderFailed">;
    confirmation: Result.ResultAsync<Confirmation, "EmailFailed">;
}>(x: {
    stock: Result.ResultAsync<Stock, "OutOfStock">;
    order: Result.ResultAsync<Order, "OrderFailed">;
    confirmation: Result.ResultAsync<Confirmation, "EmailFailed">;
}) => Result.ResultAsync<{
    stock: Stock;
    order: Order;
    confirmation: Confirmation;
}, "OutOfStock" | "OrderFailed" | "EmailFailed"> (+4 overloads)
sequence
({
stock: Result.ResultAsync<Stock, "OutOfStock">
stock
:
const reserveStock: (product: Product) => Result.ResultAsync<Stock, "OutOfStock">
reserveStock
(
product: Product
product
),
order: Result.ResultAsync<Order, "OrderFailed">
order
:
const createOrder: (user: User, product: Product) => Result.ResultAsync<Order, "OrderFailed">
createOrder
(
user: User
user
,
product: Product
product
),
confirmation: Result.ResultAsync<Confirmation, "EmailFailed">
confirmation
:
const sendConfirmationEmail: (user: User, product: Product) => Result.ResultAsync<Confirmation, "EmailFailed">
sendConfirmationEmail
(
user: User
user
,
product: Product
product
)
}); }; // すべて成功 await
const processPurchase: (user: User, product: Product) => Result.ResultAsync<{
    stock: Stock;
    order: Order;
    confirmation: Confirmation;
}, "OutOfStock" | "OrderFailed" | "EmailFailed">
processPurchase
(
const user: User
user
,
const book: Product
book
);
// { type: 'Success', value: { stock: {...}, order: {...}, confirmation: {...} } } // reserveStockが失敗した場合 → 即座に停止、注文とメールは処理されない await
const processPurchase: (user: User, product: Product) => Result.ResultAsync<{
    stock: Stock;
    order: Order;
    confirmation: Confirmation;
}, "OutOfStock" | "OrderFailed" | "EmailFailed">
processPurchase
(
const user: User
user
,
const gadget: Product
gadget
);
// { type: 'Failure', error: 'OutOfStock' }

collect - すべてのエラーを収集

collectすべてのResultを処理し、すべてのエラーを収集します。

import { 
import Result
Result
} from '@praha/byethrow';
// すべて成功 const
const success: Result.Result<[1, 2, 3], never[]>
success
=
import Result
Result
.
const collect: <[Result.Result<1, never>, Result.Result<2, never>, Result.Result<3, never>]>(x: [Result.Result<1, never>, Result.Result<2, never>, Result.Result<3, never>]) => Result.Result<[1, 2, 3], never[]> (+4 overloads)
collect
([
import Result
Result
.
const succeed: <1>(value: 1) => Result.Result<1, never> (+1 overload)
succeed
(1),
import Result
Result
.
const succeed: <2>(value: 2) => Result.Result<2, never> (+1 overload)
succeed
(2),
import Result
Result
.
const succeed: <3>(value: 3) => Result.Result<3, never> (+1 overload)
succeed
(3),
]); // { type: 'Success', value: [1, 2, 3] } // 複数の失敗 - すべてのエラーを収集 const
const failure: Result.Result<[1, never, never], ("error1" | "error2")[]>
failure
=
import Result
Result
.
const collect: <[Result.Result<1, never>, Result.Result<never, "error1">, Result.Result<never, "error2">]>(x: [Result.Result<1, never>, Result.Result<never, "error1">, Result.Result<never, "error2">]) => Result.Result<[1, never, never], ("error1" | "error2")[]> (+4 overloads)
collect
([
import Result
Result
.
const succeed: <1>(value: 1) => Result.Result<1, never> (+1 overload)
succeed
(1),
import Result
Result
.
const fail: <"error1">(error: "error1") => Result.Result<never, "error1"> (+1 overload)
fail
('error1'),
import Result
Result
.
const fail: <"error2">(error: "error2") => Result.Result<never, "error2"> (+1 overload)
fail
('error2'),
]); // { type: 'Failure', error: ['error1', 'error2'] }

オブジェクトでの使用

import { 
import Result
Result
} from '@praha/byethrow';
// すべて成功 const
const success: Result.Result<{
    name: "Alice";
    age: 30;
    email: "alice@example.com";
}, never[]>
success
=
import Result
Result
.
const collect: <{
    name: Result.Result<"Alice", never>;
    age: Result.Result<30, never>;
    email: Result.Result<"alice@example.com", never>;
}>(x: {
    name: Result.Result<"Alice", never>;
    age: Result.Result<30, never>;
    email: Result.Result<"alice@example.com", never>;
}) => Result.Result<{
    name: "Alice";
    age: 30;
    email: "alice@example.com";
}, never[]> (+4 overloads)
collect
({
name: Result.Result<"Alice", never>
name
:
import Result
Result
.
const succeed: <"Alice">(value: "Alice") => Result.Result<"Alice", never> (+1 overload)
succeed
('Alice'),
age: Result.Result<30, never>
age
:
import Result
Result
.
const succeed: <30>(value: 30) => Result.Result<30, never> (+1 overload)
succeed
(30),
email: Result.Result<"alice@example.com", never>
email
:
import Result
Result
.
const succeed: <"alice@example.com">(value: "alice@example.com") => Result.Result<"alice@example.com", never> (+1 overload)
succeed
('alice@example.com'),
}); // { type: 'Success', value: { name: 'Alice', age: 30, email: 'alice@example.com' } } // 複数の失敗 - すべてのエラーを収集 const
const result: Result.Result<{
    name: never;
    age: never;
    email: "alice@example.com";
}, ("名前は必須です" | "無効な年齢")[]>
result
=
import Result
Result
.
const collect: <{
    name: Result.Result<never, "名前は必須です">;
    age: Result.Result<never, "無効な年齢">;
    email: Result.Result<"alice@example.com", never>;
}>(x: {
    name: Result.Result<never, "名前は必須です">;
    age: Result.Result<never, "無効な年齢">;
    email: Result.Result<"alice@example.com", never>;
}) => Result.Result<{
    name: never;
    age: never;
    email: "alice@example.com";
}, ("名前は必須です" | "無効な年齢")[]> (+4 overloads)
collect
({
name: Result.Result<never, "名前は必須です">
name
:
import Result
Result
.
const fail: <"名前は必須です">(error: "名前は必須です") => Result.Result<never, "名前は必須です"> (+1 overload)
fail
('名前は必須です'),
age: Result.Result<never, "無効な年齢">
age
:
import Result
Result
.
const fail: <"無効な年齢">(error: "無効な年齢") => Result.Result<never, "無効な年齢"> (+1 overload)
fail
('無効な年齢'),
email: Result.Result<"alice@example.com", never>
email
:
import Result
Result
.
const succeed: <"alice@example.com">(value: "alice@example.com") => Result.Result<"alice@example.com", never> (+1 overload)
succeed
('alice@example.com'),
}); // { type: 'Failure', error: ['名前は必須です', '無効な年齢'] }

例:並列APIデータ集約

一般的なユースケースは、複数の独立したAPIからデータを取得することです。 collect では、すべてのAPI呼び出しが並列で行われ、複数のサービスが失敗した場合、すべてのエラーがまとめて報告されます。

import { 
import Result
Result
} from '@praha/byethrow';
const
const fetchUserDashboard: (userId: string) => Promise<Result.Result<{
    user: User;
    orders: Orders;
    reviews: Reviews;
}, FetchError[]>>
fetchUserDashboard
= async (
userId: string
userId
: string) => {
// 3つのAPI呼び出しはすべて並列で実行 return
import Result
Result
.
const collect: <{
    user: Result.ResultAsync<User, FetchError>;
    orders: Result.ResultAsync<Orders, FetchError>;
    reviews: Result.ResultAsync<Reviews, FetchError>;
}>(x: {
    user: Result.ResultAsync<User, FetchError>;
    orders: Result.ResultAsync<Orders, FetchError>;
    reviews: Result.ResultAsync<Reviews, FetchError>;
}) => Result.ResultAsync<{
    user: User;
    orders: Orders;
    reviews: Reviews;
}, FetchError[]> (+4 overloads)
collect
({
user: Result.ResultAsync<User, FetchError>
user
:
const fetchUser: (id: string) => Result.ResultAsync<User, FetchError>
fetchUser
(
userId: string
userId
),
orders: Result.ResultAsync<Orders, FetchError>
orders
:
const fetchOrders: (userId: string) => Result.ResultAsync<Orders, FetchError>
fetchOrders
(
userId: string
userId
),
reviews: Result.ResultAsync<Reviews, FetchError>
reviews
:
const fetchReviews: (userId: string) => Result.ResultAsync<Reviews, FetchError>
fetchReviews
(
userId: string
userId
),
}); }; // すべてのAPIが成功 await
const fetchUserDashboard: (userId: string) => Promise<Result.Result<{
    user: User;
    orders: Orders;
    reviews: Reviews;
}, FetchError[]>>
fetchUserDashboard
('user-123');
// { // type: 'Success', // value: { // user: { id: 'user-123', name: 'Alice' }, // orders: [{ id: 'order-123', name: 'Product A' }], // reviews: [{ id: 'review-123', comment: 'Great!' }] // }, // } // 複数のAPIが失敗 - すべてのエラーが収集される await
const fetchUserDashboard: (userId: string) => Promise<Result.Result<{
    user: User;
    orders: Orders;
    reviews: Reviews;
}, FetchError[]>>
fetchUserDashboard
('invalid-user');
// { // type: 'Failure', // error: [ // 'User not found', // 'Orders fetch failed', // ], // }

collect は非同期操作を並列で実行するため、すべてのAPI呼び出しが同時に開始され、順次実行と比較してパフォーマンスが向上します。 さらに、複数のサービスが失敗した場合、すべてのエラーがまとめて報告されるため、デバッグが容易になります。

変換関数の使用方法

両方の関数は、値をResultに変換するマッパー関数を受け入れます。

sequence

import { 
import Result
Result
} from '@praha/byethrow';
const
const parseNumbers: (strings: string[]) => Result.Result<number[], `\u7121\u52B9\u306A\u6570\u5024: ${string}`>
parseNumbers
= (
strings: string[]
strings
: string[]) => {
return
import Result
Result
.
const sequence: <string[], (str: string) => Result.Failure<`\u7121\u52B9\u306A\u6570\u5024: ${string}`> | Result.Success<number>>(x: string[], fn: (str: string) => Result.Failure<`\u7121\u52B9\u306A\u6570\u5024: ${string}`> | Result.Success<number>) => Result.Result<number[], `\u7121\u52B9\u306A\u6570\u5024: ${string}`> (+4 overloads)
sequence
(
strings: string[]
strings
, (
str: string
str
) => {
const
const num: number
num
=
function parseInt(string: string, radix?: number): number

Converts a string to an integer.

@paramstring A string to convert into a number.@paramradix A value between 2 and 36 that specifies the base of the number in string. If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. All other strings are considered decimal.
parseInt
(
str: string
str
, 10);
if (
var Number: NumberConstructor

An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.

Number
.
NumberConstructor.isNaN(number: unknown): boolean

Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number). Unlike the global isNaN(), Number.isNaN() doesn't forcefully convert the parameter to a number. Only values of the type number, that are also NaN, result in true.

@paramnumber A numeric value.
isNaN
(
const num: number
num
)) {
return
import Result
Result
.
const fail: <`\u7121\u52B9\u306A\u6570\u5024: ${string}`>(error: `\u7121\u52B9\u306A\u6570\u5024: ${string}`) => Result.Result<never, `\u7121\u52B9\u306A\u6570\u5024: ${string}`> (+1 overload)
fail
(`無効な数値: ${
str: string
str
}`);
} return
import Result
Result
.
const succeed: <number>(value: number) => Result.Result<number, never> (+1 overload)
succeed
(
const num: number
num
);
}); };
const parseNumbers: (strings: string[]) => Result.Result<number[], `\u7121\u52B9\u306A\u6570\u5024: ${string}`>
parseNumbers
(['1', '2', '3']);
// { type: 'Success', value: [1, 2, 3] }
const parseNumbers: (strings: string[]) => Result.Result<number[], `\u7121\u52B9\u306A\u6570\u5024: ${string}`>
parseNumbers
(['1', 'abc', 'xyz']);
// { type: 'Failure', error: '無効な数値: abc' }

collect

import { 
import Result
Result
} from '@praha/byethrow';
const
const parseNumbers: (strings: string[]) => Result.Result<number[], `\u7121\u52B9\u306A\u6570\u5024: ${string}`[]>
parseNumbers
= (
strings: string[]
strings
: string[]) => {
return
import Result
Result
.
const collect: <string[], (str: string) => Result.Failure<`\u7121\u52B9\u306A\u6570\u5024: ${string}`> | Result.Success<number>>(x: string[], fn: (str: string) => Result.Failure<`\u7121\u52B9\u306A\u6570\u5024: ${string}`> | Result.Success<number>) => Result.Result<number[], `\u7121\u52B9\u306A\u6570\u5024: ${string}`[]> (+4 overloads)
collect
(
strings: string[]
strings
, (
str: string
str
) => {
const
const num: number
num
=
function parseInt(string: string, radix?: number): number

Converts a string to an integer.

@paramstring A string to convert into a number.@paramradix A value between 2 and 36 that specifies the base of the number in string. If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal. All other strings are considered decimal.
parseInt
(
str: string
str
, 10);
if (
var Number: NumberConstructor

An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers.

Number
.
NumberConstructor.isNaN(number: unknown): boolean

Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number). Unlike the global isNaN(), Number.isNaN() doesn't forcefully convert the parameter to a number. Only values of the type number, that are also NaN, result in true.

@paramnumber A numeric value.
isNaN
(
const num: number
num
)) {
return
import Result
Result
.
const fail: <`\u7121\u52B9\u306A\u6570\u5024: ${string}`>(error: `\u7121\u52B9\u306A\u6570\u5024: ${string}`) => Result.Result<never, `\u7121\u52B9\u306A\u6570\u5024: ${string}`> (+1 overload)
fail
(`無効な数値: ${
str: string
str
}`);
} return
import Result
Result
.
const succeed: <number>(value: number) => Result.Result<number, never> (+1 overload)
succeed
(
const num: number
num
);
}); };
const parseNumbers: (strings: string[]) => Result.Result<number[], `\u7121\u52B9\u306A\u6570\u5024: ${string}`[]>
parseNumbers
(['1', '2', '3']);
// { type: 'Success', value: [1, 2, 3] }
const parseNumbers: (strings: string[]) => Result.Result<number[], `\u7121\u52B9\u306A\u6570\u5024: ${string}`[]>
parseNumbers
(['1', 'abc', 'xyz']);
// { type: 'Failure', error: ['無効な数値: abc', '無効な数値: xyz'] }

非同期の動作

ResultAsync(非同期Result)を使用する場合、sequencecollect は異なる動作をします。

sequence - 順次実行

sequence は非同期操作を順次(次々と)実行します。 各 Result は次の処理の前に待機され、失敗が発生すると即座に実行が停止します。

import { 
import Result
Result
} from '@praha/byethrow';
const
const fetchUser: (id: string) => Result.ResultAsync<string, string>
fetchUser
= (
id: string
id
: 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
<string, string> =>
import Result
Result
.
const succeed: <Promise<string>>(value: Promise<string>) => Result.ResultAsync<string, never> (+1 overload)
succeed
(
var Promise: PromiseConstructor

Represents the completion of an asynchronous operation

Promise
.
PromiseConstructor.resolve<string>(value: string): Promise<string> (+2 overloads)

Creates a new resolved promise for the provided value.

@paramvalue A promise.@returnsA promise whose internal state matches the provided promise.
resolve
(`User ${
id: string
id
}`));
const
const fetchOrder: (id: string) => Result.ResultAsync<string, string>
fetchOrder
= (
id: string
id
: 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
<string, string> =>
import Result
Result
.
const succeed: <Promise<string>>(value: Promise<string>) => Result.ResultAsync<string, never> (+1 overload)
succeed
(
var Promise: PromiseConstructor

Represents the completion of an asynchronous operation

Promise
.
PromiseConstructor.resolve<string>(value: string): Promise<string> (+2 overloads)

Creates a new resolved promise for the provided value.

@paramvalue A promise.@returnsA promise whose internal state matches the provided promise.
resolve
(`Order ${
id: string
id
}`));
// 操作は順次実行される:fetchUserが完了してからfetchOrderが開始 const
const result: Result.Result<{
    user: string;
    order: string;
}, string>
result
= await
import Result
Result
.
const sequence: <{
    user: Result.ResultAsync<string, string>;
    order: Result.ResultAsync<string, string>;
}>(x: {
    user: Result.ResultAsync<string, string>;
    order: Result.ResultAsync<string, string>;
}) => Result.ResultAsync<{
    user: string;
    order: string;
}, string> (+4 overloads)
sequence
({
user: Result.ResultAsync<string, string>
user
:
const fetchUser: (id: string) => Result.ResultAsync<string, string>
fetchUser
('1'),
order: Result.ResultAsync<string, string>
order
:
const fetchOrder: (id: string) => Result.ResultAsync<string, string>
fetchOrder
('100'),
}); // { type: 'Success', value: { user: 'User 1', order: 'Order 100' } }

collect - 並列実行

collectPromise.all() を使用して非同期操作を並列で実行します。 すべての操作が同時に開始され、すべての結果がまとめて待機されます。

import { 
import Result
Result
} from '@praha/byethrow';
const
const fetchUser: (id: string) => Result.ResultAsync<string, string>
fetchUser
= (
id: string
id
: 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
<string, string> =>
import Result
Result
.
const succeed: <Promise<string>>(value: Promise<string>) => Result.ResultAsync<string, never> (+1 overload)
succeed
(
var Promise: PromiseConstructor

Represents the completion of an asynchronous operation

Promise
.
PromiseConstructor.resolve<string>(value: string): Promise<string> (+2 overloads)

Creates a new resolved promise for the provided value.

@paramvalue A promise.@returnsA promise whose internal state matches the provided promise.
resolve
(`User ${
id: string
id
}`));
const
const fetchOrder: (id: string) => Result.ResultAsync<string, string>
fetchOrder
= (
id: string
id
: 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
<string, string> =>
import Result
Result
.
const succeed: <Promise<string>>(value: Promise<string>) => Result.ResultAsync<string, never> (+1 overload)
succeed
(
var Promise: PromiseConstructor

Represents the completion of an asynchronous operation

Promise
.
PromiseConstructor.resolve<string>(value: string): Promise<string> (+2 overloads)

Creates a new resolved promise for the provided value.

@paramvalue A promise.@returnsA promise whose internal state matches the provided promise.
resolve
(`Order ${
id: string
id
}`));
// 操作は並列で実行される:両方が同時に開始 const
const result: Result.Result<{
    user: string;
    order: string;
}, string[]>
result
= await
import Result
Result
.
const collect: <{
    user: Result.ResultAsync<string, string>;
    order: Result.ResultAsync<string, string>;
}>(x: {
    user: Result.ResultAsync<string, string>;
    order: Result.ResultAsync<string, string>;
}) => Result.ResultAsync<{
    user: string;
    order: string;
}, string[]> (+4 overloads)
collect
({
user: Result.ResultAsync<string, string>
user
:
const fetchUser: (id: string) => Result.ResultAsync<string, string>
fetchUser
('1'),
order: Result.ResultAsync<string, string>
order
:
const fetchOrder: (id: string) => Result.ResultAsync<string, string>
fetchOrder
('100'),
}); // { type: 'Success', value: { user: 'User 1', order: 'Order 100' } }

sequencecollect 関数の使い分け

シナリオ推奨
バリデーションですべてのエラーが必要collect
パフォーマンス向上のために並列実行が必要collect
操作が順序に依存する(例:最初の失敗で停止する必要がある)sequence
失敗の可能性が高い場合に不要な処理を最小化したいsequence

リファレンス

関数目的
sequence(array)最初の失敗で停止してそれを返す
collect(array)すべての結果を処理してすべてのエラーを収集