将抽象类作为打字稿中的参数传递

问题描述 投票:0回答:1

我正在尝试建立一个动态构建过滤字符串的类。为此,我创建了以下类:

export class UrlBuilder<T extends BaseSpalten> {

    private spalten: T;

    ....

    public filterData(config: (spalten: T, addParameter: (key: string, value: string) => void,
        addParameterListe: (key: string, value: string[]) => void) => void): UrlBuilder<T> {
        config(this.spalten, this.addQueryParameter, this.addQueryParamterList);
        return this;
    }

    ....
}

但是现在我遇到了一个问题,即“ BaseSpalten”类和扩展类是静态类:

export class BaseSpalten {
    public static AenderungVersion: string = 'AenderungVersion';
    public static Dirty: string = 'Dirty';
}

但是我需要在config函数中使用类的属性,以确保获得有效的过滤器。我如何将对静态T的引用传递给config函数?

Here is a sample Playground link for better understanding

typescript generics static
1个回答
1
投票

据我所知,我们可以将您的问题简化为以下问题。给定具有某些静态属性的类层次结构:

class BaseClass {
    public static staticPropBase: string = 'foo';
}

class SubClass extends BaseClass {
    public static staticPropSub: string = 'bar';
}

我们如何从类的实例访问那些静态属性?在运行时,这实际上很简单。所有JavaScript对象都有一个constructor property,它引用创建它的构造函数。因此,具有所有静态属性的constructor将为(new SubClass()).constructor

因此您可以编写此代码,它将起作用:

SubClass

但是问题是TypeScript编译器不满意。它没有意识到const subclass = new SubClass(); console.log(subclass.constructor.staticPropBase); // TS error, but "foo" at runtime console.log(subclass.constructor.staticPropSub); // TS error, but "bar" at rntime subclass.constructor构造函数。关于SubClass的所有知识就是它是subclass.constructor。确实是这样(类构造函数are函数),但不够具体以至于无济于事。

但是等等,TypeScript编译器知道难道Function的类型是(new SubClass()).constructor本身吗?是的,大概是typeof SubClassa longstanding open issue, see microsoft/TypeScript#3841为什么不自动执行此操作是因为子类构造函数不需要是其超类构造函数的有效子类型。在以下情况下:

The stated reason

即使实例类型class A { a: string = "a"; constructor() { } // no param } class B extends A { b: number; constructor(b: number) { // one param super(); this.b = b; } } 是实例类型B的子类型,其构造函数A也是not子类型typeof B(因为typeof A的构造函数需要一个参数,而B则不是):

A

[如果TypeScript编译器自动为const a: A = new B(123); // okay const _A: typeof A = B; // error! Type 'typeof B' is not assignable to type 'typeof A'.(2322) 提供A类型的constructor属性,并且typeof AB类型的constructor属性,则实例类型typeof B将不再是有效的子类型B的值,而子类型的A模型将失败。

Blecch。但是,如果TS可以比extends做得更好,那肯定会很好。但是,即使他们最终做出了更改,您也会遇到问题[[today。您现在可以做什么?[也许最好的当前解决方法是手动声明您的类实例具有正确类型的Function属性。由于您的类构造函数为空,因此constructortypeof SubClass的有效子类型,因此不会出现上述问题。 (如果确实出现,则可以使用typeof BaseClass之类的类型来保留静态属性,但忽略构造函数签名。可根据要求提供更多信息。)


该声明有点奇怪,但是看起来像这样:

Pick<typeof SubClass, keyof typeof SubClass>

(请注意,对于TS3.7及更高版本,应使用class BaseClass { declare ["constructor"]: typeof BaseClass; // TS 3.7+ //["constructor"]!: typeof BaseClass; // TS 3.6- public static staticPropBase: string = 'foo'; } class SubClass extends BaseClass { declare ["constructor"]: typeof SubClass; // TS 3.7+ //["constructor"]!: typeof SubClass; // TS 3.6- public static staticPropSub: string = 'bar'; } ,而对于TS2.7至TS3.6,应使用a declare property modifier。它们基本上执行相同的操作。根据需要提供更多信息。]

现在,下面的方法就可以了:

declare

否则,您始终可以只使用a definite assignment assertion来禁止编译器的警告:

const subclass = new SubClass(); console.log(subclass.constructor.staticPropBase); // okay, "foo" console.log(subclass.constructor.staticPropSub); // okay, "bar"

我个人宁愿强烈键入类定义,但类型断言也将起作用。

好的,希望能有所帮助;祝你好运!


type assertions
© www.soinside.com 2019 - 2024. All rights reserved.