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

条件类型能否检测类型参数是否因无候选实参而使用默认值?

区分TypeScript类型参数是值推导还是默认约束得到的

问题场景

你希望在TypeScript类型系统中区分:类型参数是从具体值推导而来,还是因为未提供对应属性而 fallback 到类型约束的范围。当前代码中X1和X2结果一致,无法区分两种场景:

type Test<A extends string | number> = {
    a?: A
}
type Infer<T extends Test<any>> = T extends Test<infer A> ? A : never

const v1 = {}
const v2 = { a: 'a' as string | number }

type X1 = Infer<typeof v1> // 当前结果:string | number
type X2 = Infer<typeof v2> // 当前结果:string | number

解决方案

可以通过精确判断类型是否包含明确的a属性来区分这两种情况。利用TypeScript条件类型的属性匹配特性,对未提供a的场景返回自定义标记类型:

type Test<A extends string | number> = {
    a?: A
}

type Infer<T extends Test<any>> = 
  // 匹配明确包含a属性的类型,推导实际A类型
  T extends { a: infer A } ? A : 
  // 匹配未提供a属性的空对象,返回标记类型(也可以换成never等)
  T extends {} ? 'DerivedFromConstraint' : 
  never

const v1 = {}
const v2 = { a: 'a' as string | number }

type X1 = Infer<typeof v1> // "DerivedFromConstraint"
type X2 = Infer<typeof v2> // string | number

原理说明

  • 对于typeof v1,其类型为{},不包含明确的a属性,因此进入第二个分支,返回自定义标记类型,代表该类型参数是从约束范围 fallback 而来;
  • 对于typeof v2,其类型明确包含a: string | number属性,因此匹配第一个分支,推导出实际的类型参数值。

如果不需要自定义标记,也可以返回never来区分,根据实际需求调整即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:25:22