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

TypeScript中检查对象含指定键并取值的类型错误解决问询

解决TypeScript中in操作符无法自动缩小联合索引类型的问题

你遇到的问题是TypeScript的常见限制:虽然food in FRUIT_COLORS能在运行时判断键是否存在,但TypeScript无法自动将联合类型Food缩小为FRUIT_COLORS的键类型,导致索引时出现类型错误。下面提供两种无需手动强制转换类型的解决方案:

方案一:自定义类型守卫函数

通过自定义类型守卫函数,让TypeScript明确识别in判断后的类型范围:

const FRUIT_COLORS = {
  apple: "red",
  orange: "orange",
  banana: "yellow"
} as const;

const VEGETABLE_COLORS = {
  carrot: "orange",
  broccoli: "green",
  asparagus: "green"
} as const;

type Fruit = keyof typeof FRUIT_COLORS;
type Vegetable = keyof typeof VEGETABLE_COLORS;
type Food = Fruit | Vegetable;

// 自定义类型守卫,判断key是否属于目标对象的键类型
function isKeyOf<T extends object>(obj: T, key: unknown): key is keyof T {
  return key in obj;
}

export function color(food: Food) {
  if (isKeyOf(FRUIT_COLORS, food)) {
    return FRUIT_COLORS[food]; // 此处food类型自动缩小为Fruit
  }
  return VEGETABLE_COLORS[food]; // 此处food类型自动缩小为Vegetable
}

这里用as const确保对象的键和值类型被精确推断,自定义的isKeyOf函数会告诉TypeScript:当判断为真时,food就是目标对象的键类型,从而消除索引错误。

方案二:合并对象后直接索引

如果业务允许,将两个颜色对象合并为一个,直接通过Food类型索引,这是最简洁的解决方式:

const FRUIT_COLORS = {
  apple: "red",
  orange: "orange",
  banana: "yellow"
} as const;

const VEGETABLE_COLORS = {
  carrot: "orange",
  broccoli: "green",
  asparagus: "green"
} as const;

// 合并两个对象并锁定类型
const FOOD_COLORS = { ...FRUIT_COLORS, ...VEGETABLE_COLORS } as const;
type Food = keyof typeof FOOD_COLORS;

export function color(food: Food) {
  return FOOD_COLORS[food]; // 类型完全匹配,无任何错误
}

这种方式去掉了分支判断,直接通过合并后的对象索引,TypeScript能准确推断返回值为所有颜色的联合类型,代码更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:05:51