残余プロパティを使った分割代入
オブジェクトから特定のプロパティを除外して、残りのプロパティを新しいオブジェクトとして取得するパターン。 書いていて思いついたので、メモしておく!
パターン例
例えば特大オブジェクトがあるとする
// オリジナルのユーザーデータから特定フィールドを除外してコピーを作成 const { id: _id, password: _password, createdAt: _createdAt, updatedAt: _updatedAt, ...userDataWithoutMetadata } = originalUserData
このパターンの優れた点
| ポイント | 説明 |
|---|---|
| Immutable | 元のoriginalUserDataを変更せず、新しいオブジェクトを生成 |
| 型安全 | TypeScriptがuserDataWithoutMetadataの型を自動推論(除外プロパティを除いたOmit<T, 'id' | 'password' | ...>相当) |
| 宣言的 | 「何を除外するか」が明確に見える |
_プレフィックス |
「意図的に未使用」を示す慣例(ESLintのno-unused-vars対策にもなる) |
代替案の問題点
// NG例1: 手動コピー(DRY違反、メンテナンス困難) const userDataWithoutMetadata = { name: originalUserData.name, email: originalUserData.email, // ... 大量のプロパティを列挙 } // NG例2: delete使用(型が崩れる、意図が不明瞭) const userDataWithoutMetadata = { ...originalUserData } delete userDataWithoutMetadata.id delete userDataWithoutMetadata.password
汎用テンプレート
// 特定プロパティを除外してオブジェクトをコピー const { propToRemove1: _propToRemove1, // _ = 「意図的に捨てる」 propToRemove2: _propToRemove2, ...rest // 残りのプロパティを取得 } = sourceObject // TypeScriptの型推論 // rest → Omit<typeof sourceObject, 'propToRemove1' | 'propToRemove2'>
ユースケース
- 新規作成用データ: 既存データから
idを除外してPOSTリクエスト用に変換 - セキュリティ:
passwordやtokenを除外してログ出力やレスポンスに使用 - 状態リセット: 特定のフィールドをクリアしたコピーを作成
- APIレスポンス整形: 不要なメタデータを除外してフロントに返却