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

如何基于JSON对象的值创建TypeScript联合类型且避免重复定义

问题

现有用于下拉菜单的JSON结构如下:

[
  { "label": "整套房源", "value": "entire_place" },
  { "label": "共享房间", "value": "shared_room" },
  { "label": "私人房间", "value": "private_room" }
]

其中label是用户可见文本,value是存入数据库的值。需要生成对应的TypeScript联合类型:

type Property = "entire_place" | "private_room" | "shared_room";

如何实现无需重复定义数据?避免新增选项时同时修改JSON对象与类型;若无法实现,有什么更好的存储带标签数据并用于校验的替代方案?


解决方案

方法一:从常量数组自动推导联合类型

TypeScript支持通过as const断言保留字面量类型,以此实现从选项数组自动生成联合类型,只需维护数组一处即可:

  1. 定义带as const断言的选项常量:
const propertyOptions = [
  { label: "整套房源", value: "entire_place" },
  { label: "共享房间", value: "shared_room" },
  { label: "私人房间", value: "private_room" },
] as const;

as const会让TypeScript将数组元素、对象属性都视为不可变的字面量类型,而非宽泛的string。

  1. 自动推导联合类型:
// 提取数组中每个元素的value属性类型,组成联合类型
type Property = typeof propertyOptions[number]["value"];

此时Property的类型自动等同于"entire_place" | "shared_room" | "private_room",新增或修改选项时,只需调整propertyOptions数组,类型会自动同步更新。

如果选项来自外部JSON文件,需在tsconfig.json中开启resolveJsonModule选项,导入后同样用上述方式推导类型:

import propertyOptions from './property-options.json' assert { type: 'json' };
type Property = typeof propertyOptions[number]["value"];

方法二:用枚举生成选项数组(反向维护)

若场景更强调类型约束,可先定义枚举,再从枚举自动生成下拉菜单选项数组,同样只需维护枚举一处:

  1. 定义枚举:
enum Property {
  EntirePlace = "entire_place",
  SharedRoom = "shared_room",
  PrivateRoom = "private_room"
}
  1. 生成选项数组:
const propertyOptions = Object.entries(Property).map(([key, value]) => ({
  // 将枚举键转换为友好的用户可见标签(如EntirePlace → "Entire Place")
  label: key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()),
  value: value
}));

这种方式适合需要在代码中直接使用枚举值(如接口定义、条件判断)的场景,新增选项时只需修改枚举,选项数组会自动生成。


内容的提问来源于stack exchange,提问作者user19910212

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 14:40:51