使用泛型交叉类型时出现‘T可实例化为任意类型’错误
TypeScript泛型交叉类型调用报错问题
我尝试通过交叉类型向编译器提示期望的类型(因为泛型条件判断的求值会被延迟),定义了如下类型:
type ArgType<T> = T & (T extends MyType ? ({ myArg?: MyInterface<T> }) : never)
但调用使用该类型作为参数的函数时,出现如下错误:
'T' could be instantiated with an arbitrary type which could be unrelated to '{ myArg: this; }'
完整代码如下:
type MyType = 'foo'; interface MyInterface<T extends MyType> { myField: T; } type ArgType<T> = T & (T extends MyType ? ({ myArg?: MyInterface<T> }) : never) function myFunc<T>(arg: ArgType<T>) { return arg; } class MyClass<T extends MyType> implements MyInterface<T> { constructor(readonly myField: T) {} invoke() { const result = myFunc({ myArg: this }); } }
问题原因
报错的核心是myFunc的泛型T没有约束,编译器无法推断出T必须是MyType的子类型。当传入{myArg: this}时,编译器不知道T和MyInterface<T>之间的关联,担心T可能被实例化为任意无关类型,导致类型不兼容。
解决方法
方法1:给myFunc的泛型添加约束
给myFunc的泛型T加上extends MyType的约束,明确T只能是MyType的子类型,这样编译器就能正确关联MyInterface<T>和传入的this类型:
function myFunc<T extends MyType>(arg: ArgType<T>) { return arg; }
方法2:调用时显式指定泛型参数
如果不想修改myFunc的定义,可以在调用时显式指定泛型T为当前类的泛型参数:
invoke() { const result = myFunc<T>({ myArg: this }); }
方法3:简化ArgType的定义
可以调整ArgType的结构,让条件判断更直观,本质和原定义逻辑一致,但能帮助编译器更好地推导:
type ArgType<T> = T extends MyType ? T & { myArg?: MyInterface<T> } : never;
内容的提问来源于stack exchange,提问作者Mister Epic
相关产品推荐
相关产品推荐

