文档描述了如何在类工厂方法中使用类类型:
function create<Type>(c: { new (): Type }): Type {
return new c();
}
这是一种非常常见的方法,但缺少构造函数参数。因此,通常类类型扩展如下:
function create<Type>(c: { new (...args: any[]): Type }): Type {
return new c();
}
这很好用,但是使用了any
关键字,我想避免使用。在一个具体的例子中,我创建了一个构造函数类型:
export type SymbolConstructor<T extends BaseSymbol> = new (...args: unknown[]) => T;
我想创建的类有不同的构造函数参数,所以我需要这个rest参数。
然而,这只是部分工作。在库(一个节点模块)中,我定义了一切正常。在一个类中,我有这样的方法:
public addNewSymbolOfType<T extends BaseSymbol>(t: SymbolConstructor<T>,
parent: ScopedSymbol | undefined, ...args: unknown[]): T {
const result = new t(...args);
if (!parent || parent === this) {
this.addSymbol(result);
} else {
parent.addSymbol(result);
}
return result;
}
并且是这样使用的:
symbolTable.addNewSymbolOfType(FieldSymbol, classSymbol, `myField`);
其中FieldSymbol
是从BaseSymbol
派生的类,并且工作良好(在模块的单元测试中)。
在一个有这个节点模块作为依赖的项目中,我做了同样的事情:
const s = symbolTable.addNewSymbolOfType(FieldSymbol, mainSymbol, member);
但现在我得到一个错误:
“类型'typeof FieldSymbol'的参数不能分配给类型'SymbolConstructor'的参数。
构造签名的类型不兼容。
键入“new(名称:字符串,值:未知,类型?:类型|undefined)=〉FieldSymbol'不可赋值给类型'new(...args:unknown[])=〉FieldSymbol'.
参数“name”和“args”的类型不兼容。
类型“unknown”不能分配给类型“string”。
当我使用any
作为构造函数参数时,这种情况也有效。
如果要使用unknown
而不是any
,正确的方法是什么?
1条答案
按热度按时间w8f9ii691#
我草拟了一个简化版本的API,请参阅typescript playground,它看起来对类型很满意。关键是
Args extends unknown[]
在签名中有自己的泛型位置。