【发布时间】:2020-11-28 23:46:04
【问题描述】:
我有一个包含大量子类的基类。
class SuperClass{
constructor(){}
}
class SubClass1 extends SuperClass{
constructor(){super()}
SubClass1Prop(){}
}
class SubClass2 extends SuperClass{
constructor(){super()}
SubClass2Prop(){}
}
我有一个包含不同子类混合的列表,我已将其类型声明为SuperClass[],因为它们共享那个共同的祖先。
let list:SuperClass[] = [];
list.push(new SubClass1());
list.push(new SubClass2());
我有一个函数,它将子类作为参数,然后过滤列表以返回该子类的实例。
此函数的类型声明取自此 SO 答案 (Type for function that takes a class as argument, and returns an instance of that class),稍有不同之处在于我返回的是列表而不是单个对象。
错误就在这里。我控制可以将哪些类型传递给 filterList 函数,并且可以保证它始终是 SuperClass 的子级。但是,TypeScript 无法知道这一点。如何声明我传递给此函数的任何 className 必须始终是 SuperClass 的子级,并且不能是“任意类型”?
function filterList<T>(className: { new():T }):T[] {
//TS2322: Type 'SuperClass[]' is not assignable to type 'T[]'.
// Type 'SuperClass' is not assignable to type 'T'.
// 'T' could be instantiated with an arbitrary type which could be unrelated to 'SuperClass'
return list.filter(obj => obj instanceof className);
}
上述函数的示例使用场景。 (删除空安全检查以简化演示)
我要求在不使用“as”关键字显式类型转换的情况下,将过滤列表正确识别为具有 SubClass1[] 类型,而不是 SuperClass[] 或 any[] 类型。目前所有这些要求都满足了,但是TS错误在上面的函数中。任何解决方案都不得破坏此处的类型检查。
let filteredList = filterList(SubClass1);
filteredList[0].SubClass1Prop();
【问题讨论】:
标签: typescript