如何使用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

