【问题标题】:typescript get typeof this in static method打字稿在静态方法中获取类型
【发布时间】:2017-12-16 20:01:18
【问题描述】:
import Collection from 'collection'

class Model {
}

class Book extends Model {
    static collection = new Collection<Book>('books')
}

我想将集合定义从 Book 移动到 Model:

import Collection from 'collection'

class Model {
    static _collection

    static get collection() {
         let typename = this.name // = Book
         if(!this._collection) {
             this._collection = new Collection<...>('books')
         }
         return this._collection
    }
}

class Book extends Model {
}

我可以使用this.name 获取父类(模型)中的类名(书)。但是如何引用 Book 的类型以与new Collection&lt;&gt; 一起使用?

【问题讨论】:

标签: typescript inheritance


【解决方案1】:

集合成员是静态的。静态成员始终属于声明它的 type,因此通过将集合移动到基本类型 Model,您实际上使 Model 的所有子类型使用完全相同的集合( Model 中声明的那个)。

因此,如果Model 的所有子类型都使用相同的集合,那么将Book.collection 的类型设置为Collection&lt;Book&gt; 是没有意义的,而实际上它是Collection&lt;Model&gt;

我建议您考虑一下您要在这里实现的目标。通常,静态成员可能不是最好的主意,所以不妨考虑在那里做些其他事情。


话虽如此,如果集合不是静态成员,那么这里仍然存在概念上的问题:静态类型的重点是在编译时获得类型信息。当编译成 JavaScript 时,该集合根本不会被输入,也不会强制执行在编译时仍然存在的类型信息。

这就是为什么你根本不能使用只存在于运行时的类型信息。并且 this.name 将在编译时进行评估:编译器现在没有真正的方法可以将其设为 Book 并且集合将属于该类型。

变量类型支持的解决方案是泛型,就像集合已经做的那样。因此,如果您希望Model 中的成员具有变量类型,那么您需要将Model 设为通用:

class Model<T> {
    private _collection : T[];

    public get collection() {
        if (!this._collection) {
            this._collection = new Collection<T>();
        }
        return this._collection;
    }
}

class Book extends Model<Book> { … }

现在Book 将有一个Collection&lt;Book&gt; 成员,在编译时可用。

【讨论】:

    猜你喜欢
    • 2020-04-20
    • 2021-08-13
    • 2017-03-03
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    • 2022-01-25
    相关资源
    最近更新 更多