【问题标题】:generic type usage as value in an abstract class<T, K extends keyof T>泛型类型用作抽象类中的值<T, K extends keyof T>
【发布时间】:2020-09-11 18:09:17
【问题描述】:

我正在尝试将一些逻辑移至抽象类。 考虑具有以下约束的抽象泛型类:

abstract class AbstractVersion<
    TModel extends object,
    TProperty extends keyof TModel,
    TValue = TModel[TProperty]> {

    private _version: TValue;
    public get version(): TValue {
        return this._version;
    }
}

所以这可以通过例子来扩展

class MyVersionedModel extends AbstractVersion<MyModel, 'MyNumericId'>

到目前为止,一切都很好。但是现在我想使用我的 TProperty-type 作为值,这样的事情可能吗?

abstract class AbstractVersion<
    TModel extends object,
    TProperty extends keyof TModel,
    TValue = TModel[TProperty]> {

    private _version: TValue;
    public get version(): TValue {
        return this._version;
    }

    set(model: TModel): void {
        this._version = model[TProperty];
    }

    apply(fx: (property: string, value: TValue) => boolean): boolean {
        return fx(TProperty.toString(), this.version);
    }
}

很明显我遇到了语法错误'TProperty' only refers to a type, but is being used as a value here.model[TProperty]TProperty.toString() 上,但是有没有办法将 TProperty 作为值访问?

【问题讨论】:

  • 我认为不可能,因为泛型在运行时不可用。您需要在运行时以某种方式传递属性名称(可能在构造函数中?)
  • 我同意这一点。您可以尝试使用您的类型的构造函数的名称,但这非常不可靠,因为它会随着缩小而改变。我建议要么通过构造函数传递名称,要么通过返回名称的抽象方法(或包含它的字段,但该方法的优点是它可以是抽象的并且可以强制执行)。
  • 那么使用“重复”构造函数参数constructor(private property: TProperty) 是最好的方法吗?实现class MyVersionedModel extends AbstractVersion&lt;MyModel, 'OtherIdentifier'&gt; { constructor() { super('OtherIdentifier'); } }

标签: typescript typescript-typings typescript-generics


【解决方案1】:

这是不可能的,因为您的所有输入在运行时都不可用。请记住,Typescript 被编译为 JavaScript,而 JavaScript 不知道类型。

我认为,您需要在某处指定有效密钥,正如 cmets 中建议的那样,作为构造函数参数将是最佳位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-29
    • 2019-01-08
    • 2020-08-22
    • 1970-01-01
    • 2017-07-25
    • 1970-01-01
    • 2013-08-13
    • 2019-02-02
    相关资源
    最近更新 更多