0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【TypeScript】Record型で動的プロパティの型安全性を保つテクニック

Posted at

ECサイトの商品フィルタリングダッシュボードのデータ集計など、動的なグルーピング処理を実装する場面がありますが、実行時まで分からないキーを持つオブジェクトは型安全性を確保するのが困難です。

// このように2段階ネストしたグルーピングを型安全に実装したい
{ "Electronics": { "High-end": [product1], "Budget": [product2] } }

今回はそれを叶えるためにRecord型とreduceを組み合わせた動的グルーピングの実装方法を紹介します。

Record型による型安全な動的構造

// Record型による動的グルーピング
type GroupedData = Record<string, Product[]>

interface Product {
  id: string
  productProperties: Array<{
    property: { name: string }
    propertyOptions: Array<{ option: { value: string } }>
  }>
}

reduceによる動的グルーピング

const groupProductsByProperty = (
  products: Product[],
  propertyName: string,
): GroupedData => {
  return products.reduce<GroupedData>((acc, product) => {
    // 商品から指定されたプロパティを検索
    const property = product.productProperties.find(
      (prop) => prop.property.name === propertyName,
    )
    
    if (!property || property.propertyOptions.length === 0) {
      // プロパティが見つからない場合は「その他」に分類
      if (!acc['その他']) acc['その他'] = []
      acc['その他'].push(product)
    } else {
      // 各プロパティオプションに対して商品を追加
      property.propertyOptions.forEach((option) => {
        const { value } = option.option
        if (!acc[value]) acc[value] = []
        acc[value].push(product)
      })
    }
    return acc
  }, {})
}

使用例

// 基本的な使用方法
const groupedData = groupProductsByProperty(products, 'category')

// Record型による型安全なアクセス
Object.entries(groupedData).forEach(([category, items]) => {
  console.log(`${category}: ${items.length}件`)
})

// 特定カテゴリの商品を安全に取得
const electronicsProducts = groupedData['Electronics'] || []

まとめ

技術 効果
Record型 動的キーでも型安全性を保持
reduce + find 関数型で配列からオブジェクトへの変換
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?