Skip to content

Commit f89230c

Browse files
authored
Merge branch 'main' into test/fake-timer
2 parents 486cb92 + 7adabb5 commit f89230c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2452
-23
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# es-toolkit Changelog
22

3+
## Version v1.42.0
4+
5+
Released on November 17th, 2025.
6+
7+
- Added new async utilities: `filterAsync`, `flatMapAsync`, `forEachAsync`, `mapAsync`, `reduceAsync`, and `limitAsync` for handling asynchronous operations.
8+
- Exported `ThrottleOptions` and `DebounceOptions` interfaces for better type support.
9+
- Fixed `isFinite` to implement type predicate to narrow type to number.
10+
- Fixed `isSafeInteger` to implement type predicate to narrow type to number.
11+
- Fixed `omit` to prevent adding index properties to array-like objects.
12+
- Fixed `mergeWith` to remove unnecessary nullish coalescing for 100% branch coverage.
13+
- Fixed `compat/updateWith` to remove unreachable code and add prototype pollution test.
14+
- Updated documentation headings for consistency.
15+
- Improved test coverage for `compat/mergeWith`, `compat/unset`, `get`, `toMerged`, `mergeWith`, and `compat/intersectionBy` with additional edge cases and security tests.
16+
17+
We sincerely thank @Debbl, @wo-o29, @raon0211, @Yeom-JinHo, @sukvvon, and @D-Sketon for their contributions. We appreciate your great efforts!
18+
319
## Version v1.41.0
420

521
Released on October 24th, 2025.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# filterAsync
2+
3+
非同期条件関数を使用して配列をフィルタリングし、条件を満たす要素のみを含む新しい配列を返します。
4+
5+
```typescript
6+
const filtered = await filterAsync(array, predicate);
7+
```
8+
9+
## 参照
10+
11+
### `filterAsync(array, predicate, options?)`
12+
13+
API呼び出しやデータベースクエリなどの非同期操作で配列をフィルタリングする場合は、`filterAsync`を使用してください。通常の`filter`とは異なり、非同期条件関数をサポートし、`concurrency`オプションで並行実行数を制限できます。
14+
15+
```typescript
16+
import { filterAsync } from 'es-toolkit/array';
17+
18+
// APIでユーザーステータスを確認して、アクティブなユーザーのみをフィルタリングします。
19+
const users = [{ id: 1 }, { id: 2 }, { id: 3 }];
20+
const activeUsers = await filterAsync(users, async user => {
21+
return await checkUserStatus(user.id);
22+
});
23+
// 返り値:アクティブなユーザーのみを含む配列
24+
25+
// 並行実行数を制限してサーバー負荷を軽減します。
26+
const numbers = [1, 2, 3, 4, 5];
27+
const evenNumbers = await filterAsync(numbers, async n => await isEvenAsync(n), { concurrency: 2 });
28+
// 最大2つの操作のみが同時に実行されます。
29+
```
30+
31+
`concurrency`オプションは、外部API呼び出しを制限したり、システムリソースを効率的に管理したりするのに役立ちます。指定しない場合、すべての操作が同時に実行されます。
32+
33+
```typescript
34+
import { filterAsync } from 'es-toolkit/array';
35+
36+
// 最大3つのAPI呼び出しのみを同時に実行します。
37+
const items = await filterAsync(largeArray, async item => await validateItem(item), { concurrency: 3 });
38+
```
39+
40+
#### パラメータ
41+
42+
- `array` (`readonly T[]`):フィルタリングする配列です。
43+
- `predicate` (`(item: T, index: number, array: readonly T[]) => Promise<boolean>`):各要素をテストする非同期関数です。真と評価される値を返すと、その要素が結果に含まれます。
44+
- `options` (`FilterAsyncOptions`, オプショナル):並行実行を制御するオプションです。
45+
- `concurrency` (`number`, オプショナル):同時に実行できる最大操作数です。指定しない場合、すべての操作が同時に実行されます。
46+
47+
#### 戻り値
48+
49+
(`Promise<T[]>`):条件関数が真と評価される値を返した要素のみを含む新しい配列のPromiseを返します。
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# flatMapAsync
2+
3+
非同期関数を使用して配列の各要素を変換し、結果を1レベル平坦化して新しい配列を返します。
4+
5+
```typescript
6+
const result = await flatMapAsync(array, callback);
7+
```
8+
9+
## 参照
10+
11+
### `flatMapAsync(array, callback, options?)`
12+
13+
各要素が複数の値を返す非同期変換を実行する場合は、`flatMapAsync`を使用してください。`mapAsync`を呼び出した後に`flat()`を実行するのと同等ですが、より効率的です。
14+
15+
```typescript
16+
import { flatMapAsync } from 'es-toolkit/array';
17+
18+
// 各ユーザーの投稿を取得して1つの配列に結合します。
19+
const users = [{ id: 1 }, { id: 2 }];
20+
const allPosts = await flatMapAsync(users, async user => {
21+
return await fetchUserPosts(user.id);
22+
});
23+
// 返り値:[post1, post2, post3, ...](すべてのユーザーの投稿が1つの配列に)
24+
25+
// 並行実行数を制限します。
26+
const numbers = [1, 2, 3];
27+
const results = await flatMapAsync(numbers, async n => await fetchRelatedItems(n), { concurrency: 2 });
28+
// 最大2つの操作のみが同時に実行されます。
29+
```
30+
31+
各コールバック関数は配列を返す必要があり、返されたすべての配列が1つの配列にマージされます。`concurrency`オプションを使用すると、並行実行を制限してサーバー負荷を管理できます。
32+
33+
```typescript
34+
import { flatMapAsync } from 'es-toolkit/array';
35+
36+
// 各カテゴリーの商品リストを取得して1つの配列にします。
37+
const categories = ['electronics', 'books', 'clothing'];
38+
const products = await flatMapAsync(categories, async category => await fetchProducts(category), { concurrency: 2 });
39+
// 返り値:すべてのカテゴリーの商品を含む単一の配列
40+
```
41+
42+
#### パラメータ
43+
44+
- `array` (`readonly T[]`):変換する配列です。
45+
- `callback` (`(item: T, index: number, array: readonly T[]) => Promise<R[]>`):各要素を配列に変換する非同期関数です。
46+
- `options` (`FlatMapAsyncOptions`, オプショナル):並行実行を制御するオプションです。
47+
- `concurrency` (`number`, オプショナル):同時に実行できる最大操作数です。指定しない場合、すべての操作が同時に実行されます。
48+
49+
#### 戻り値
50+
51+
(`Promise<R[]>`):1レベル平坦化された変換値の配列のPromiseを返します。
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# forEachAsync
2+
3+
配列の各要素に対して非同期関数を実行します。
4+
5+
```typescript
6+
await forEachAsync(array, callback);
7+
```
8+
9+
## 参照
10+
11+
### `forEachAsync(array, callback, options?)`
12+
13+
配列の各要素に対して副作用を伴う非同期操作を実行する場合は、`forEachAsync`を使用してください。通常の`forEach`とは異なり、すべての非同期操作が完了したときに解決されるPromiseを返します。
14+
15+
```typescript
16+
import { forEachAsync } from 'es-toolkit/array';
17+
18+
// すべてのユーザー情報を更新します。
19+
const users = [{ id: 1 }, { id: 2 }, { id: 3 }];
20+
await forEachAsync(users, async user => {
21+
await updateUser(user.id);
22+
});
23+
// すべてのユーザー更新が完了しました。
24+
25+
// 並行実行数を制限します。
26+
const items = [1, 2, 3, 4, 5];
27+
await forEachAsync(items, async item => await processItem(item), { concurrency: 2 });
28+
// 最大2つの項目のみが同時に処理されます。
29+
```
30+
31+
`concurrency`オプションを使用すると、並行実行を制限してサーバーやデータベースへの負荷を制御できます。ログ記録、ファイルアップロード、データベース更新など、値を返さない操作に便利です。
32+
33+
```typescript
34+
import { forEachAsync } from 'es-toolkit/array';
35+
36+
// ファイルを順次アップロードします。
37+
const files = ['file1.txt', 'file2.txt', 'file3.txt'];
38+
await forEachAsync(files, async file => await uploadFile(file), { concurrency: 1 });
39+
// 一度に1つずつアップロードされます。
40+
```
41+
42+
#### パラメータ
43+
44+
- `array` (`readonly T[]`):反復処理する配列です。
45+
- `callback` (`(item: T, index: number, array: readonly T[]) => Promise<void>`):各要素に対して実行する非同期関数です。
46+
- `options` (`ForEachAsyncOptions`, オプショナル):並行実行を制御するオプションです。
47+
- `concurrency` (`number`, オプショナル):同時に実行できる最大操作数です。指定しない場合、すべての操作が同時に実行されます。
48+
49+
#### 戻り値
50+
51+
(`Promise<void>`):すべての操作が完了したときに解決されるPromiseを返します。
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# limitAsync
2+
3+
非同期関数の最大並行実行数を制限する新しい関数を作成します。
4+
5+
```typescript
6+
const limitedFunc = limitAsync(asyncFunc, concurrency);
7+
```
8+
9+
## 参照
10+
11+
### `limitAsync(callback, concurrency)`
12+
13+
複数回呼び出される非同期関数の並行実行数を制限したい場合は、`limitAsync`を使用してください。指定された数だけ同時に実行され、追加の呼び出しは実行中の操作が完了するまで待機します。
14+
15+
```typescript
16+
import { limitAsync } from 'es-toolkit/array';
17+
18+
// 最大3つのリクエストのみを同時に実行するように制限します。
19+
const limitedFetch = limitAsync(async url => {
20+
return await fetch(url);
21+
}, 3);
22+
23+
const urls = ['url1', 'url2', 'url3', 'url4', 'url5'];
24+
await Promise.all(urls.map(url => limitedFetch(url)));
25+
// 最初の3つが先に実行され、完了すると残りが実行されます。
26+
```
27+
28+
外部API呼び出しやデータベースクエリなど、リソースを大量に使用する操作の負荷を制御するのに便利です。レート制限のあるAPIを使用する場合やサーバー負荷を管理する必要がある場合に特に効果的です。
29+
30+
```typescript
31+
import { limitAsync } from 'es-toolkit/array';
32+
33+
// 重い計算を最大2つずつ処理します。
34+
const processItem = async item => {
35+
return await heavyComputation(item);
36+
};
37+
38+
const limitedProcess = limitAsync(processItem, 2);
39+
const items = [1, 2, 3, 4, 5];
40+
await Promise.all(items.map(item => limitedProcess(item)));
41+
// 最大2つの項目のみが同時に処理されます。
42+
```
43+
44+
#### パラメータ
45+
46+
- `callback` (`F extends (...args: any[]) => Promise<any>`):並行実行数を制限する非同期関数です。
47+
- `concurrency` (`number`):同時に実行できる最大操作数です。
48+
49+
#### 戻り値
50+
51+
(`F`):並行実行制限が適用された新しい関数を返します。元の関数と同じインターフェースを持ちます。
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# mapAsync
2+
3+
非同期関数を使用して配列の各要素を変換し、新しい配列を返します。
4+
5+
```typescript
6+
const transformed = await mapAsync(array, callback);
7+
```
8+
9+
## 参照
10+
11+
### `mapAsync(array, callback, options?)`
12+
13+
配列の各要素に対して非同期変換操作を実行する場合は、`mapAsync`を使用してください。API呼び出しやデータベースクエリなど、各要素を非同期的に処理する必要がある場合に便利です。
14+
15+
```typescript
16+
import { mapAsync } from 'es-toolkit/array';
17+
18+
// 各ユーザーの詳細情報を取得します。
19+
const users = [{ id: 1 }, { id: 2 }, { id: 3 }];
20+
const userDetails = await mapAsync(users, async user => {
21+
return await fetchUserDetails(user.id);
22+
});
23+
// 返り値:[{ id: 1, name: '...' }, { id: 2, name: '...' }, { id: 3, name: '...' }]
24+
25+
// 並行実行数を制限します。
26+
const numbers = [1, 2, 3, 4, 5];
27+
const results = await mapAsync(numbers, async n => await slowOperation(n), { concurrency: 2 });
28+
// 最大2つの操作のみが同時に実行されます。
29+
```
30+
31+
`concurrency`オプションを使用すると、並行実行を制限してサーバー負荷を制御したり、APIレート制限を守ったりできます。指定しない場合、すべての操作が同時に実行されます。
32+
33+
```typescript
34+
import { mapAsync } from 'es-toolkit/array';
35+
36+
// 大量の画像を変換しますが、サーバー負荷を考慮して並行処理数を制限します。
37+
const imageUrls = [...]; // 多くの画像URL
38+
const processedImages = await mapAsync(
39+
imageUrls,
40+
async (url) => await processImage(url),
41+
{ concurrency: 5 }
42+
);
43+
// 一度に最大5つの画像のみが処理されます。
44+
```
45+
46+
#### パラメータ
47+
48+
- `array` (`readonly T[]`):変換する配列です。
49+
- `callback` (`(item: T, index: number, array: readonly T[]) => Promise<R>`):各要素を変換する非同期関数です。
50+
- `options` (`MapAsyncOptions`, オプショナル):並行実行を制御するオプションです。
51+
- `concurrency` (`number`, オプショナル):同時に実行できる最大操作数です。指定しない場合、すべての操作が同時に実行されます。
52+
53+
#### 戻り値
54+
55+
(`Promise<R[]>`):変換された値で構成される新しい配列のPromiseを返します。
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# reduceAsync
2+
3+
非同期リデューサー関数を使用して配列を単一の値に縮約します。
4+
5+
```typescript
6+
const result = await reduceAsync(array, reducer, initialValue);
7+
```
8+
9+
## 参照
10+
11+
### `reduceAsync(array, reducer, initialValue)`
12+
13+
各要素を順次処理して配列を1つの値に縮約する場合は、`reduceAsync`を使用してください。リデューサー関数は左から右へ各要素に順次適用され、前の呼び出しの累積結果を次の呼び出しに渡します。
14+
15+
```typescript
16+
import { reduceAsync } from 'es-toolkit/array';
17+
18+
// 各数値の非同期値を取得して合計します。
19+
const numbers = [1, 2, 3, 4, 5];
20+
const sum = await reduceAsync(numbers, async (acc, n) => acc + (await fetchValue(n)), 0);
21+
// 返り値:すべての取得値の合計
22+
23+
// 配列をオブジェクトに変換します。
24+
const users = [{ id: 1 }, { id: 2 }, { id: 3 }];
25+
const userMap = await reduceAsync(
26+
users,
27+
async (acc, user) => {
28+
const details = await fetchUserDetails(user.id);
29+
acc[user.id] = details;
30+
return acc;
31+
},
32+
{} as Record<number, any>
33+
);
34+
// 返り値:{ 1: {...}, 2: {...}, 3: {...} }
35+
```
36+
37+
他の非同期配列メソッドとは異なり、`reduceAsync`は各要素を順次処理する必要があるため、並行実行をサポートしていません。前のステップの結果が次のステップに必要だからです。
38+
39+
#### パラメータ
40+
41+
- `array` (`readonly T[]`):縮約する配列です。
42+
- `reducer` (`(accumulator: U, currentValue: T, currentIndex: number, array: readonly T[]) => Promise<U>`):各要素を処理する非同期関数です。累積値と現在の値を受け取り、新しい累積値を返します。
43+
- `initialValue` (`U`):アキュムレーターの初期値です。
44+
45+
#### 戻り値
46+
47+
(`Promise<U>`):最終的な累積値のPromiseを返します。
48+
49+
---
50+
51+
### `reduceAsync(array, reducer)`
52+
53+
初期値なしで配列を縮約する場合、最初の要素が初期値として使用され、2番目の要素からリデューサー関数が適用されます。
54+
55+
```typescript
56+
import { reduceAsync } from 'es-toolkit/array';
57+
58+
// 初期値なしで合計を計算します。
59+
const numbers = [1, 2, 3, 4, 5];
60+
const sum = await reduceAsync(numbers, async (acc, n) => acc + n);
61+
// 返り値:15 (1 + 2 + 3 + 4 + 5)
62+
63+
// 空の配列はundefinedを返します。
64+
const emptyArray: number[] = [];
65+
const result = await reduceAsync(emptyArray, async (acc, n) => acc + n);
66+
// 返り値:undefined
67+
```
68+
69+
初期値なしで空の配列に対して`reduceAsync`を呼び出すと、`undefined`を返します。
70+
71+
#### パラメータ
72+
73+
- `array` (`readonly T[]`):縮約する配列です。
74+
- `reducer` (`(accumulator: T, currentValue: T, currentIndex: number, array: readonly T[]) => Promise<T>`):各要素を処理する非同期関数です。累積値と現在の値を受け取り、新しい累積値を返します。
75+
76+
#### 戻り値
77+
78+
(`Promise<T | undefined>`):最終的な累積値のPromiseを返します。配列が空の場合は`undefined`を返します。

docs/ja/reference/error/AbortError.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,6 @@ await fetchData(controller.signal); // AbortErrorをスロー
5050

5151
- `message` (`string`, オプション): エラーメッセージです。デフォルト値は`'The operation was aborted'`です。
5252

53-
### 戻り値
53+
#### 戻り値
5454

5555
(`AbortError`): 中断された操作を表すエラーインスタンスを返します。`Error`を継承しており、`name`プロパティは`'AbortError'`です。

docs/ja/reference/error/TimeoutError.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,6 @@ await fetchWithTimeout('https://example.com/api/slow');
4949

5050
- `message` (`string`, オプション): エラーメッセージです。デフォルト値は`'The operation was timed out'`です。
5151

52-
### 戻り値
52+
#### 戻り値
5353

5454
(`TimeoutError`): タイムアウトした操作を表すエラーインスタンスを返します。`Error`を継承しており、`name`プロパティは`'TimeoutError'`です。

0 commit comments

Comments
 (0)