我有一个抽象类Thingydoo
和一个扩展它的类Thingymabob
。我在Thingydoo
上有一些静态方法,我想创建一些Thingymabob
中存在的类型。我尝试这样做的根本原因是为了给不同类型的Thingydoo
给予一个API,以便以编程方式为每种类型创建不同的选项。
interface MyStuff {
[name: string]: {someParam: string}
};
type Something<T> = {
thing: T;
}
abstract class Thingydoo {
// here - on this line - TypeScript uses "this" to mean Thingydoo, not the Thingymabob that comes from it
static testWithTypeParam(thing: ReturnType<typeof this.differentFunc>): Something<ReturnType<typeof this.differentFunc>> {
// here, in this line, TypeScript _knows_ that this.name is Thingymabob, not Thingydoo.
console.log("hi! this is a " + this.name);
return {thing: thing};
}
static differentFunc() : MyStuff {
return {};
}
}
class Thingymabob extends Thingydoo {
static differentFunc(): {beans: {someParam: string}} {
return {beans: {someParam: "test"}};
}
static feedMeBeans(beansContainer: {beans: {someParam: string}}) {
console.log(beansContainer.beans.someParam);
}
}
let something = Thingymabob.testWithTypeParam({beans: {someParam: "test3"}});
// so this, despite making sense and compiling to JS fine + running fine in JS, issues a compiler error in tsc, because it doesn't realise the beans type is MyStuff compatible.
Thingymabob.feedMeBeans(something.thing);
在这个例子中,我希望testWithTypeParam
返回一个{beans: {someParam: string}}
类型的对象,以便与Thingymabob
上的feedMeBeans
方法兼容。但这似乎根本不可能:我找不到做这件事的方法。我尝试过使用多态的this
类型,如示例代码所示,但在该路由上没有取得任何进展:这似乎完全没有区别(Playground)。
我错过了什么明显的东西吗?
1条答案
按热度按时间enyaitl31#
TypeScript不直接支持
static
成员的多态this
类型。在microsoft/TypeScript#5863上有一个长期的开放特性请求,但它还没有实现(还没有?)除非发生这种情况,否则你就得努力解决它。对于static methods,一个常见的解决方法是将
T
类型中的方法generic约束为您希望this
成为的某个超类型(如果您的类名是Foo
,则可能是typeof Foo
,但它不必是),然后为该方法提供T
类型的this
参数。然后(这可能是您遗漏的部分)使用类型T
代替类型this
。所以你不用你会
对于类似于
请注意,
T
是一个类型,而不是一个值,所以不能写typeof T.differentFunc
。相反,您需要“T
的属性类型,其键是"differentFunc"
”,您可以通过indexed access typeT["differentFunc"]
获得。现在它可以按预期工作:
Playground链接到代码