是否可以在typescript
的泛型函数中专门化泛型类的模板类型?
假设我有一个通用接口和一个以接口构造函数为参数的函数:
interface IA<T> {
func(arg: T)
}
function g<T, IAType extends IA<T>>(
constructor: { new(): IAType }
): (arg: T) => IAType {
const ins = new constructor();
return arg => {
ins.func(arg);
return ins;
}
}
然后我提供类实现IA<T>
,
class A implements IA<{ key: string }> {
func(arg: { key: string }) {
console.log(arg.key);
}
}
const t = g(A); // type of t is (arg: {}) => A
如何编写函数g
或类A
,以便函数g
可以由于传递参数而专门化正确的模板类型?我想要最后的t
类型为(arg: {key: string}) => A
答案 0 :(得分:1)
constructor
的{{1}}参数的这种类型
g
并没有真正施加约束, constructor: { new(): IAType }
中的func()
必须具有IAType
作为其参数类型。唯一的约束是T
,这意味着IAType extends IA<T>
中的func
可以具有任何类型,只要它与IAType
兼容即可。推理算法可能以最小类型func(arg: T)
开始,验证{}
与func(arg: {})
兼容并且就此停止。
更加严格的func(arg: T)
类型有助于:
constructor
interface IA<T> {
func(arg: T): void
}
function g<T, IAType extends IA<T>>(
constructor: { new(): IA<T> & IAType }
): (arg: T) => IAType {
const ins = new constructor();
return arg => {
ins.func(arg);
return ins;
}
}
class A implements IA<{ key: string }> {
func(arg: { key: string }) {
console.log(arg.key);
}
}
const t = g(A); // type of t is (arg: { key: string; }) => A
都是必需的。如果只有IA<T> & IAType
,则会根据需要推断出IA<T>
类型,但是返回类型将仅为arg
,而不是IA<T>
。