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

TypeScript中如何用泛型与三元运算符定义普通对象函数参数类型?

问题根源:分布式条件类型的特性

问题出在哪?

你的Test泛型触发了分布式条件类型——当泛型参数是联合类型时,TypeScript会自动把联合类型拆成单个成员,分别执行条件判断,再把结果重新合并成新的联合类型。

针对Test<'keyA' | 'keyB'>:

  • 先对'keyA'应用条件逻辑,得到{ keyA: 'test' }
  • 再对'keyB'应用条件逻辑,得到{ keyB: 'test' }
  • 最终生成的类型是{ keyA: 'test' } | { keyB: 'test' }

为什么变量赋值没问题?

{ keyA: 'test', keyB: 'test' }是这个联合类型的子类型——它同时满足联合中两个成员的结构,TypeScript允许将更具体的类型赋值给更宽泛的联合类型,因此变量obj不会报错。

为什么函数参数报错?

函数参数的类型是联合类型时,TypeScript会做严格的类型校验:它只能保证传入的参数是联合中的某一个成员,无法确定具体是哪一个。当你访问obj.keyA时,联合类型里的{ keyB: 'test' }并没有keyA属性,因此触发类型错误。

解决方案:阻止分布式条件类型

要让联合类型作为一个整体参与条件判断,只需把泛型参数用方括号包裹,破坏分布式条件类型的触发机制:

type Test<K extends string | {}> = [K] extends [string]
    ? { [key in K]: 'test' }
    : K;

type Obj = Test<'keyA' | 'keyB'>; // 现在类型是 { keyA: 'test'; keyB: 'test' }

const fn = (obj: Test<'keyA' | 'keyB'>) => {
    return obj.keyA; // 不再报错
}

这样'keyA' | 'keyB'会被当作一个整体判断是否属于string类型,此时key in K会遍历联合类型的所有成员,生成包含所有键的对象类型,而非联合类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 13:50:28