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

TypeScript 4.0.2中如何将unknown类型收窄为字符串枚举?

在TypeScript 4.0.2中将unknown收窄为字符串枚举的解决方案

你的问题在于,TypeScript 4.0.2无法通过Object.values(Fruit).includes()的调用自动将string类型收窄为Fruit枚举类型——内置的数组includes方法的类型守卫逻辑不支持这种枚举成员的推导,所以即便检查通过,变量类型仍会停留在string。

以下是两种可行的解决方式:

方式一:自定义类型守卫(推荐)

通过自定义类型守卫函数,明确告知TypeScript当检查通过时变量的类型为Fruit,这是类型安全且可复用的方案:

enum Fruit {
  Apple = "Apple",
  Banana = "Banana",
}

function getFruitPrice(x: Fruit) {
  // 示例实现
  return x === Fruit.Apple ? 5 : 3;
}

// 自定义类型守卫:判断值是否为Fruit枚举成员
function isFruit(value: unknown): value is Fruit {
  return typeof value === 'string' && Object.values(Fruit).includes(value);
}

const fruit: unknown = "Apple"; // 示例未知类型值

// 使用类型守卫进行类型收窄
if (!isFruit(fruit)) {
  throw new Error("Invalid fruit type");
}

// 此时fruit的类型已被正确收窄为Fruit
const price = getFruitPrice(fruit);

方式二:类型断言(简易方案)

如果只是临时场景,也可以在完成所有检查后手动使用类型断言,但这种方式依赖开发者确保检查逻辑的正确性,不如类型守卫安全:

enum Fruit {
  Apple = "Apple",
  Banana = "Banana",
}

function getFruitPrice(x: Fruit) {
  // 示例实现
  return x === Fruit.Apple ? 5 : 3;
}

const fruit: unknown = "Banana"; // 示例未知类型值

// 先检查是否为字符串
if (typeof fruit !== 'string') throw new Error();
// 再检查是否属于枚举成员
if (!Object.values(Fruit).includes(fruit)) throw new Error();

// 手动断言为Fruit类型
const price = getFruitPrice(fruit as Fruit);

需要注意的是,在TypeScript 4.0.2中,Object.values(Fruit)返回的类型是string[](字符串枚举的成员值本质是字符串),因此直接传入fruit(已确认是string类型)即可,无需额外的类型断言。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:10:25