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

使用Omit处理函数参数时TypeScript丢失类型信息问题

解决TypeScript中联合类型使用Omit后的类型收窄错误

问题原因

你遇到的错误是因为Omit<Foo, 'value'>的行为和预期不符。当Omit作用于联合类型时,它会对每个联合成员单独执行Omit操作:

  • 原Foo中的{ value: string }去掉value属性后变成空对象{}
  • 另外两个成员{ oldValue: string }和{ newValue: string }不受影响(因为它们没有value属性)

最终Omit<Foo, 'value'>的实际类型是{} | { oldValue: string } | { newValue: string },这就导致:

  1. 检查'oldValue' in input时,input可能是空对象{},所以input.oldValue被推断为unknown,无法赋值给string
  2. 最后返回input.newValue时,input可能是空对象或{ oldValue: string },这两种类型都没有newValue属性,所以报错

解决方案

不要用Omit,直接从Foo中排除带有value属性的成员,或者显式定义目标类型:

方案1:使用Exclude排除指定成员

type Foo = { value: string } | { oldValue: string } | { newValue: string };

function getResults(input: Foo): string {
  if ('value' in input) {
    return input.value;
  }
  if ('oldValue' in input) {
    return input.oldValue;
  }
  return input.newValue;
}

function getResults2(input: Exclude<Foo, { value: string }>): string {
  if ('oldValue' in input) {
    return input.oldValue;
  }
  return input.newValue;
}

Exclude<Foo, { value: string }>会直接从联合类型Foo中移除匹配{ value: string }的成员,得到的类型是{ oldValue: string } | { newValue: string },此时类型收窄可以正常工作,不会出现错误。

方案2:显式定义目标类型

如果逻辑简单,也可以直接写出需要的类型,更直观:

type Foo = { value: string } | { oldValue: string } | { newValue: string };
type FooWithoutValue = { oldValue: string } | { newValue: string };

function getResults(input: Foo): string {
  if ('value' in input) {
    return input.value;
  }
  if ('oldValue' in input) {
    return input.oldValue;
  }
  return input.newValue;
}

function getResults2(input: FooWithoutValue): string {
  if ('oldValue' in input) {
    return input.oldValue;
  }
  return input.newValue;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:33:34