【问题标题】: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<> 一起使用?
【问题讨论】:
标签:
typescript
inheritance
【解决方案1】:
集合成员是静态的。静态成员始终属于声明它的 type,因此通过将集合移动到基本类型 Model,您实际上使 Model 的所有子类型使用完全相同的集合( Model 中声明的那个)。
因此,如果Model 的所有子类型都使用相同的集合,那么将Book.collection 的类型设置为Collection<Book> 是没有意义的,而实际上它是Collection<Model>。
我建议您考虑一下您要在这里实现的目标。通常,静态成员可能不是最好的主意,所以不妨考虑在那里做些其他事情。
话虽如此,如果集合不是静态成员,那么这里仍然存在概念上的问题:静态类型的重点是在编译时获得类型信息。当编译成 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<Book> 成员,在编译时可用。