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

如何使用infer关键字获取泛型传入的参数类型?

TypeScript中infer提取泛型参数失败问题分析与解决

问题场景

我尝试用infer关键字提取泛型传入的参数类型,数组的例子能正常工作:

type ArrayElementType<T> = T extends Array<infer E> ? E : T;
type Element = ArrayElementType<Array<number>> // Element类型为number

但换成自定义的Pluggable类型时就不符合预期:

// Pluggable仅为示例,实际会继承更复杂结构
type Pluggable<T> = T & { disabled?: boolean }
type PluggableElementType<T> = T extends Pluggable<infer E> ? E : never;

type Element= PluggableElementType<Pluggable<{prop: number}>>
// 期望Element类型为{prop: number},但实际得到{prop:number} & {disabled?: boolean}

想搞清楚:当前思路是否正确?要不要修改Pluggable类型?为什么Array接口能正常工作,是不是因为它是接口而非类型交集?

问题根源

Array<infer E>能正常提取E,核心原因是Array是泛型接口,它的泛型参数位置是明确的,TypeScript可以精准定位到泛型参数的占位,从而正确提取出E。

而你的Pluggable<T>是类型交集,当你写T extends Pluggable<infer E>时,TypeScript会把Pluggable<infer E>展开成infer E & { disabled?: boolean }。此时进行类型匹配时,TypeScript会尽可能把整个传入的类型(也就是{prop: number} & {disabled?: boolean})全量赋值给infer E——因为交集类型是扁平化的结构,TypeScript无法区分原泛型参数T和附加的{disabled?: boolean}部分,自然会把整个交集结果捕获为E。

解决办法

方案1:将Pluggable改为泛型接口

和Array的实现逻辑对齐,把Pluggable改成泛型接口,让泛型参数位置明确:

interface Pluggable<T> extends T {
  disabled?: boolean;
}

type PluggableElementType<T> = T extends Pluggable<infer E> ? E : never;

type Element = PluggableElementType<Pluggable<{prop: number}>>
// 此时Element类型为{prop: number},符合预期

这种方式最直接,TypeScript能准确识别接口的泛型参数位置,infer就能精准提取出原类型。

方案2:保留类型别名,调整infer匹配逻辑

如果必须保留Pluggable作为类型别名,可以通过反向剔除disabled属性,或者调整交集顺序来提取原类型:

type Pluggable<T> = T & { disabled?: boolean }

// 方式A:用Omit剔除disabled属性
type PluggableElementType<T> = T extends Pluggable<infer E> ? Omit<T, 'disabled'> : never;

// 方式B:调整交集顺序,让infer只捕获非disabled的部分
type PluggableElementType<T> = T extends { disabled?: boolean } & infer E ? E : never;

type Element = PluggableElementType<Pluggable<{prop: number}>>
// 两种方式都能得到Element类型为{prop: number}

这里利用了TypeScript的类型分配规则,把交集的两部分拆分,让infer只捕获我们需要的原类型部分。

总结

  • 泛型接口的泛型参数有明确的占位位置,infer可以精准匹配;而类型交集是扁平化结构,无法直接区分原泛型参数和附加的交集内容。
  • 优先推荐把Pluggable改成泛型接口,逻辑更清晰;如果受限于场景必须用类型别名,就通过Omit或调整交集顺序来实现需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 16:06:25