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

如何根据对象数组的value属性定义TypeScript联合类型

解决方案

场景1:currencies数组为代码内硬编码的静态值

这种情况可以直接通过TypeScript的类型收窄能力提取value的联合类型:

// 用as const将数组内的字面量值收窄为精确的字面量类型,而不是宽的string类型
const currencies = [
  { text: 'American dollars', value: 'USD' },
  { text: 'Euros', value: 'EU' }
] as const

// 提取所有value的联合类型
type CurrencyValue = typeof currencies[number]['value']

// 此时currency变量的类型就是 'USD' | 'EU',只能赋值为这两个值
let currency: CurrencyValue

如果需要保留对currencies数组结构的约束,避免写的时候出错,可以配合satisfies关键字:

// 定义通用的Currency结构类型
type Currency<T extends string = string> = {
  text: string
  value: T
}

const currencies = [
  { text: 'American dollars', value: 'USD' },
  { text: 'Euros', value: 'EU' }
] as const satisfies Currency[]

// 提取的CurrencyValue类型依然是 'USD' | 'EU'
type CurrencyValue = typeof currencies[number]['value']

场景2:currencies数组来自后端接口/数据库的动态值

TypeScript是静态类型系统,编译后类型信息会全部擦除,无法提前预知运行时才返回的后端数据结构。这种情况下需要结合运行时校验+类型守卫实现约束:

// 先定义你预期支持的合法货币值联合类型
type CurrencyValue = 'USD' | 'EU'
type Currency = {
  text: string
  value: CurrencyValue
}

// 类型守卫:判断传入的字符串是否是合法的CurrencyValue
function isCurrencyValue(value: string): value is CurrencyValue {
  return ['USD', 'EU'].includes(value)
}

// 校验后端返回的原始货币数组是否符合结构要求
function validateCurrencies(rawArr: {text: string, value: string}[]): rawArr is Currency[] {
  return rawArr.every(item => isCurrencyValue(item.value))
}

// 调用接口获取数据后先做校验
const rawCurrencies = await fetch('/api/currencies').then(res => res.json())
if (!validateCurrencies(rawCurrencies)) {
  throw new Error('后端返回的货币数据不合法')
}
// 校验通过后rawCurrencies的类型会被收窄为Currency[]

// 校验用户输入/赋值的currency是否合法
const inputValue = 'USD' // 示例值,可来自用户输入、其他逻辑返回
if (isCurrencyValue(inputValue)) {
  // 这里inputValue的类型已经被收窄为CurrencyValue,可以安全赋值
  let currency: CurrencyValue = inputValue
}

注意:如果后端返回的货币值是完全动态、无法提前枚举的,你没法在编译阶段做静态约束,只能在运行时做合法性判断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 19:15:03