我想在子类和生成器上指定一些数据的形状,这些数据创建具有一些通用T
的类。
我最初的想法是使用如下的泛型(简化示例),但是当我调用makeMyClass
并且当我返回new classRef
时,它会给我以下错误:
Type 'T' is not assignable to type 'DataInterface'
为什么不是T
类型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
答案 0 :(得分:0)
嗯,您的代码中有两个问题。第一个是您将makeMyClass
定义为通用,但随后使用具体变量调用new classRef
。这意味着T
实际上可以是任何内容,它必须是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
无法分配给typeof MySuperClass
类型的参数。此外,使用构造函数类型将限制可以传递给具有该确切签名的构造函数的类型。如果你从MySuperClass
创建一个新的派生类,但是它有一个带有两个参数的构造函数,那么它就不可能在这个函数中使用它,因为它需要一个只需要一个类型为{的参数的构造函数{1}}。这可以防止运行时错误,因此您无法调用参数少于预期的构造函数。
当然,如果您希望函数是通用的,则需要传递类型为T
的第二个参数,以传递给类的构造函数。否则,正如我所解释的那样,该函数实际上不是通用的,因为它仅限于T
的类型。