打字稿:未能解决通用类装饰的签名
问题描述:
我不明白为什么需要打字原稿明确泛型类型定义为Child2
和Child3
在这种情况下:打字稿:未能解决通用类装饰的签名
abstract class Base {
public static A: string = "Fallback_A";
public DoSmthWithClassName(): string {
return "Fallback_DoSmth";
}
constructor(...args: any[]); // overload for type consistency with children
constructor(x: string)
{ }
}
// typeof any non-abstract child of Base
type BaseType = typeof Base & (new(...args: any[]) => Base);
// decorator, modifies methods and static properties
function ClassDecorator<T extends BaseType>(valueA: string): (value: T) => T {
return (value: T) => {
value.prototype.DoSmthWithClassName =() => value.name + ".DoSmth." + value.A;
value.A = value.name + valueA;
return value;
}
}
@ClassDecorator("Foo") // OK
class Child0 extends Base {
}
@ClassDecorator("Foo") // OK
class Child1 extends Base {
constructor(x: number) {
super(x.toString());
}
}
@ClassDecorator("Foo") // Unable to resolve...
class Child2 extends Base {
static X: number = 0;
}
@ClassDecorator<typeof Child3>("Foo") // OK
class Child3 extends Base {
static X: number = 0;
}
答
的问题是,TS不能推断T的类型来自唯一参数valueA
。你想要的是在内部/恢复功能的通用参数:
// decorator, modifies methods and static properties
function ClassDecorator(valueA: string) {
return function <T extends BaseType>(value: T): T {
value.prototype.DoSmthWithClassName =() => value.name + ".DoSmth." + value.A;
value.A = value.name + valueA;
return value;
}
}
你的版本是不导致与Child0和Child1任何问题,因为它们在结构上相同的基础。
+0
我没有想到你的想法,但我决定放弃泛型并使用这种装饰器: 'function ClassDecorator(valueA:string):(value:typeof Base)=> void'因为编译器假定'value.prototype.DoSmthWithClassName'在一般情况下,类型是'any'。 –
如果装饰器的返回类型改为void,那么该代码片段运行时没有错误,但编译器在每种情况下仍然会将泛型类型解析为BaseType,而我不明白为什么。 –