具有静态的Typescript类推断

时间:2019-11-13 16:20:16

标签: typescript inheritance type-inference

import { FilterQuery } from "mongodb";

abstract class Base<T extends Base<any>> {
    public static async findOne<T extends Base<any>>(
        this: new (...a: any[]) => T,
        query: FilterQuery<T>
    ): Promise<T> {
        console.log(this.getSomeString()); // currently: "getSomeString" dosnt exists on type "new (...a: any[]) => T"
        // already tried "typeof T" - because "typeof" is not allowed on generics
        // already tried https://stackoverflow.com/a/52358194/8944059 's static solution
        // already tried "T" - which makes "this: any"
        // and i tried various other things, which resulted in "await SomeExtendingClass" cannot be assigned to "this"

        // Edit for @jcalz
        console.log(this.someProtectedMethod()); // error "someProtectedMethod" does not exists on type "this"

        return undefined;
    }

    public static getSomeString(): string {
        this.someProtectedMethod(); // this would work
        return "Hello";
    }

    // Edit for @jcalz
    protected static someProtectedMethod() {
        return "hello2";
    }
}

class SomeExtendingClass extends Base<SomeExtendingClass> {
    public someValue: string;
}

(async () => {
    await SomeExtendingClass.findOne({ someValue: "hi" });
})();

目标是在this中拥有所有静态变量,同时能够使用new this(...args)对其进行调用,并且(父类的)所有键都可以插入query中,而不必删除abstract

已尝试:
-https://stackoverflow.com/a/58037767/8944059
-https://stackoverflow.com/a/52358194/8944059的静态解决方案

PS:我不了解打字稿类型的大部分魔力,这就是为什么我要问...

PPS:here is the project i would need it

2 个答案:

答案 0 :(得分:0)

感谢@jcalz

他的答案是替换

new (...a: any[]) => T

Pick<typeof Base, keyof typeof Base> & (new (...a: any[]) => T)

这对我来说主要是

我发现这不包括protected值/函数

如果可以找到protected子问题的答案,则将对此问题进行编辑

答案 1 :(得分:0)

您的示例代码没有显示为什么根本不需要任何ggplot(df2, aes(x = New_Var, y = Mean, group = Condition)) + geom_point(aes(shape = Condition, color= Condition), stat = "identity", position = position_dodge(), size = 2) + geom_errorbar(aes(ymin = Mean - Sd, ymax = Mean + Sd, color = Condition), width = .2, position = position_dodge(.9)) + scale_shape_manual(values=c(15, 16, 17))+ scale_color_manual(values = c("black","darkgrey","darkred"), labels = c("Control","Condition 1", "Condition 2")) + scale_x_discrete(limits = c("blankcontrol","AC1","BC1","CC1","AC2","BC2","CC2") , labels = c("Blank","A","B","C","A","B","C")) + theme(axis.text.x = element_text(face = "bold",angle = 45), legend.title = element_blank()) + xlab("") + scale_y_continuous(limits = c(0,15), breaks = c(0,5,10,15))+ geom_jitter(data = dfX, aes(x = New_Var2, y = Value, shape = Condition), position=position_jitter(0.3), color = adjustcolor("black",alpha.f = 0.6), show.legend = F, size = 2) 参数。例如,以下代码甚至适用于this静态方法。 protected的默认类型仅为this

typeof Base

如果以上内容不足以满足您的用例,请编辑您的示例代码以显示某些地方可能会出现问题。大概有一些原因需要首先添加一个import { FilterQuery } from "mongodb"; abstract class Base<T extends Base<any>> { public static async findOne<T extends Base<any>>( query: FilterQuery<T> ): Promise<T> { console.log(this.getSomeString()); console.log(this.someProtectedMethod()); return undefined!; // <-- not a Promise } public static getSomeString(): string { return "Hello"; } protected static someProtectedMethod() { return "hello2"; } } class SomeExtendingClass extends Base<SomeExtendingClass> { public someValue: string = "123"; // needs initialization } (async () => { await SomeExtendingClass.findOne({ someValue: "hi" }); })(); 参数。是什么原因?

无论如何,希望能有所帮助;祝你好运!

Link to code


编辑:如果您需要this可以在this内部以零args进行构造,并且不允许以这种方式无法构造的类调用findOne(),则可以可能这样做:

findOne()

Link to code

如果您还有其他要求(例如允许为子类使用不同的构造函数参数),请告诉我。再次祝你好运!