TypeScriptで空配列の型エラーを回避する
typescript
javascript
投稿日: 2025/11/01
TypeScriptのNonEmptyArray型で空配列の型エラーを回避する
一部のライブラリでは、空配列を受け付けないメソッドがあります。NonEmptyArray型と型ガード関数を使うことで、この型エラーを安全に回避できます。
問題: 空配列を受け付けないメソッド
// ライブラリの型定義(例: Drizzle ORMのbatchメソッド) class Database { async batch<T extends [Query, ...Query[]]>(queries: T) { // ... } } // 動的に生成される配列 const queries = items.map(item => createQuery(item)); // ❌ 型エラー!queriesが空配列の可能性がある await db.batch(queries); // Error: Argument of type 'Query[]' is not assignable to parameter of type '[Query, ...Query[]]'
解決方法
型定義
type NonEmptyArray<T> = [T, ...T[]]; function isNonEmptyArray<T>(arr: T[]): arr is NonEmptyArray<T> { return arr.length > 0; }
使い方
const queries = items.map(item => createQuery(item)); // 型ガードで確認 if (isNonEmptyArray(queries)) { await db.batch(queries); // ✅ OK } else { console.log('クエリがありません'); }
// エラーをthrowする場合 if (!isNonEmptyArray(queries)) { throw new Error('クエリが空です'); } await db.batch(queries); // ✅ OK
実践例
条件付きクエリ
async function updateData(updateA: boolean, updateB: boolean) { const queries = []; if (updateA) queries.push(queryA); if (updateB) queries.push(queryB); if (isNonEmptyArray(queries)) { return await db.batch(queries); } return null; }
フィルタリング後
async function batchProcess(items: Item[]) { const queries = items .filter(item => item.isValid) .map(item => createQuery(item)); if (!isNonEmptyArray(queries)) { throw new Error('処理対象がありません'); } return await db.batch(queries); }
ヘルパー関数
async function safeBatch(queries: Query[]) { if (!isNonEmptyArray(queries)) { return null; } return await db.batch(queries); } // 使用例 const result = await safeBatch(dynamicQueries); if (result === null) { console.log('処理なし'); }
asキャストは使わない
ほかの解決方法として、asキャストを使って回避する方法もあります。
しかし、asキャストは型チェックを無視するため型推論の利益をうけづらいです。
// ❌ 危険 const queries = [] as NonEmptyArray<Query>; await db.batch(queries); // 実行時エラー!
まとめ
NonEmptyArray型: 最低1つの要素を持つ配列isNonEmptyArray関数: 型ガードとして実行時チェックasキャストではなく型ガード関数を使う
yosi
Noh を作ってるエンジニア。
