You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

转换const对象时如何保留TypeScript类型化的键与值?

保留const对象动态转换后的精确类型信息

假设有如下带as const断言的嵌套对象,它的类型是完全字面量化的:

const drinks = {
   cold: {
      juice: { 
          name: 'orange juice', 
          price: 2 
      },
      water: { 
          name: 'still water juice', 
          price: 0 
      },
   },
   warm: {
      coffee: { 
          name: 'coffee', 
          price: 1 
      },
      tea: { 
          name: 'earl gray', 
          price: 1 
      },
   }
} as const

用reduce做结构转换后,能得到扁平的目标结构,但TypeScript会把结果推断为{ [key: string]: ... },丢失了原对象的精确键和字面量类型:

const result = Object.entries(drinks).reduce(
    (result, [category, drinks]) => ({
        ...result,
        ...Object.entries(drinks).reduce(
            (mappedItems, [name, value]) => ({
                ...mappedItems,
                [name]: {
                    ...value,
                    category: category,
                },
            }),
            {},
        ),
    }),
    {},
)

要保留精确类型,需要手动定义类型工具并给转换结果指定类型:

步骤1:定义类型转换工具

写两个类型工具,把原嵌套结构转换成目标扁平结构的精确类型:

// 将每个分类下的饮料添加对应分类的字面量类型
type FlattenDrinks<T extends Record<string, Record<string, any>>> = 
  {
    [Category in keyof T]: {
      [Drink in keyof T[Category]]: T[Category][Drink] & { category: Category }
    }
  }[keyof T]

// 把交叉类型合并为单一对象类型
type Merge<T> = { [K in keyof T]: T[K] }

// 生成最终的目标类型
type FlattenedDrinks = Merge<FlattenDrinks<typeof drinks>>

步骤2:给转换函数指定类型

修改reduce的初始值,用类型断言指定为目标类型,这样TypeScript就能识别精确的键和值类型:

const result = Object.entries(drinks).reduce(
    (result, [category, drinks]) => ({
        ...result,
        ...Object.entries(drinks).reduce(
            (mappedItems, [name, value]) => ({
                ...mappedItems,
                [name]: {
                    ...value,
                    category: category,
                },
            }),
            {},
        ),
    }),
    {} as FlattenedDrinks, // 断言初始值为目标类型
)

此时result的类型会精确保留所有键(juice | water | coffee | tea),每个值的category也是对应的字面量类型(比如result.juice.category类型为"cold"),同时保留原有的name和price字面量类型。

内容的提问来源于stack exchange,提问作者Theo.T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 06:22:35