我有某种基类...
class BaseClass<ItemType> {
// Irrelevant parameters elided for simplicity...
constructor(__items: Iterable<ItemType>) {}
}
我想要一个工厂,该工厂可以返回该类或某个子类的实例,该工厂将提供消除参数的某些值。调用者可以提供要使用这些参数构造的子类的构造函数,因此让我们声明一个接口...
export interface GenericConstructorInterface<S, T extends BaseClass<S>> {
new(items: Iterable<S>): T;
}
现在我们可以声明工厂了...
// This works...
export function factory<A, B extends BaseClass<A>>(__items: Iterable<A>, subclassConstructor: GenericConstructorInterface<A, B>): B {
return new subclassConstructor(__items);
}
但是,我不想谴责所有调用者必须提供构造函数,所以我尝试
// The default parameter won't typecheck:
// Type 'typeof BaseClass' is not assignable to type 'GenericConstructorInterface<A, B>'.
// Type 'BaseClass<A>' is not assignable to type 'B'.ts(2322)
export function factory<A, B extends BaseClass<A>>(__items: Iterable<A>, subclassConstructor: GenericConstructorInterface<A, B> = BaseClass): B {
return new subclassConstructor(__items);
}
,现在默认参数不会进行类型检查。我在这里误解了什么?
答案 0 :(得分:1)
任何默认参数都必须与所有可能的类型参数兼容。由于subclassConstructor
依赖于B
,因此对于任何传入的BaseClass
,类B
都不是默认值。(B
可以是{{1 }},因此DerivedFromBaseClass
将不是BaseClass
的有效默认值。
您可以在默认参数值中使用类型断言,尽管更好的选择是使用多个重载。像这样,呼叫者无法传递与默认设置不一致的subclassConstructor
:
B