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

联合类型中离散成员的属性类型兼容性问题

联合类型中离散成员的属性类型兼容性问题

我之前还以为自己搞定过这个问题呢,结果现在又栽在这上面了。咱们先来看这个联合类型的定义:

type Handler<T> = (value: T) => void;
type Foo = { a: string; b: Handler<string> } | { a : number; b: Handler<number> }

现在假设有一个符合Foo类型的对象x,我本来想着直接这么写代码就行:

x.b(x.a);

但实际操作起来却会遇到类型报错——这是因为TypeScript没办法自动推断出x.a和x.b的类型是严格匹配的。毕竟x是联合类型,它可能是{a: string; b: Handler<string>},也可能是{a: number; b: Handler<number>},TS没办法确定这两个属性属于联合类型的同一个分支,所以会认为x.a可能是string或number,而x.b可能接受string或number,两者的类型组合不兼容。

要解决这个问题,我们可以用类型收窄的方式,让TS明确知道x属于联合类型的哪一个分支。比如直接用typeof做类型收窄:

if (typeof x.a === 'string') {
  x.b(x.a); // 这里TS能确定x.a是string,x.b接受string,完全没问题
} else {
  x.b(x.a); // 剩下的分支必然是number类型,同样能正常运行
}

如果场景更复杂,也可以自定义类型守卫函数来做收窄:

function isStringFoo(foo: Foo): foo is { a: string; b: Handler<string> } {
  return typeof foo.a === 'string';
}

function isNumberFoo(foo: Foo): foo is { a: number; b: Handler<number> } {
  return typeof foo.a === 'number';
}

// 使用时
if (isStringFoo(x)) {
  x.b(x.a);
} else if (isNumberFoo(x)) {
  x.b(x.a);
}

这样就能让TS正确识别属性之间的类型对应关系,顺利执行x.b(x.a)的操作啦。

备注:内容来源于stack exchange,提问作者flq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 17:43:00