typescript - 为什么这个泛型函数的类型参数不接受给定的类型?
问题描述
我想在一个子类和一个生成器上指定一些数据的形状,该生成器使用一些通用T
的 . 我最初的想法是使用下面的泛型(简化示例),但是当我调用makeMyClass
和返回时new classRef
,它给了我以下错误:
Type 'T' is not assignable to type 'DataInterface'
为什么不是T
type DataInterface
?
class MySuperClass<T> {
constructor(public data: T) {}
}
interface DataInterface {
name: string;
}
let initData: DataInterface = {
name: "Alice"
};
class MyClass extends MySuperClass<DataInterface>{
constructor(public data: DataInterface) {
super(data)
}
}
function makeMyClass<T>(classRef: typeof MySuperClass): MySuperClass<T> {
return new classRef(initData);
}
let a = makeMyClass<DataInterface>(MyClass);
let b = a.data
解决方案
好吧,您的代码中有两个问题。首先是您将其定义makeMyClass
为泛型,但随后您new classRef
使用具体变量进行调用。这意味着它T
不能是任何东西,它必须是 type type initData
。
除此之外,您将声明classRef
为类的类型。最好将其定义为构造函数签名,否则您将遇到问题let a = makeMyClass<>(MyClass)
您的代码将适用于这些更改:
function makeMyClass<T>(classRef: new(initData: T) => MySuperClass<T>, initData: T): MySuperClass<T> {
return new classRef(initData);
}
let a = makeMyClass(MyClass, initData);
let b = a.data
签名的new(initData: T) => MySuperClass<T>
意思是,*一个接受 T 类型参数的构造函数,并创建一个类型为 的对象MySuperClass<T>
。两者都MySuperClass<DataInterface>
符合MyClass
这个要求。但是,您会发现它MyClass
不能分配给 type 的参数typeof MySuperClass
。此外,构造函数类型的使用将限制您可以传递给具有该确切签名的构造函数的类型。如果您创建一个新的派生类,MySuperClass
但它有一个带有两个参数的构造函数,则无法将它与此函数一起使用,因为它需要一个只需要一个 type 参数的构造函数T
。这可以防止运行时错误,因此您不能调用参数少于预期的构造函数。
当然,如果你希望函数是泛型的,你需要传递 type 的第二个参数T
来传递给类的构造函数。否则,正如我所解释的,该函数不能真正是通用的,因为它仅限于initData
.
推荐阅读
- c - 用于读取浮点数的 scanf 无法按预期工作
- laravel-livewire - Livewire 多线:点击,第一个有效,其余不
- magento - Magton 1.8 无法保存配置
- xml - Toast 通知的 XML 参数
- python - Numpy:数组的迭代组合
- twitter-bootstrap-3 - Select2 中的选定选项在输入字段之外
- javascript - 在 Sequelize 中使用 AND 操作与多对多关系
- bootstrap-4 - 如何在不同的屏幕尺寸上格式化特定的填充/边距规则?
- javascript - 没有在窗口中打开弹出窗口
- wpf - Visual Studio 16.8 刚刚禁止在 WPF Core 3.1 应用程序中使用控制台?