typescript在静态方法中获取typeof

时间:2017-12-16 20:01:18

标签: typescript inheritance

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在父类(Model)中获取类名(Book)。但是,如何通过new Collection<>来引用Book的类型?

1 个答案:

答案 0 :(得分:0)

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

因此,如果Model的所有子类型都使用相同的集合,那么当Book.collection的类型实际为Collection<Book>时,Collection<Model>的类型为this.name是没有意义的。

我建议你考虑一下你想在这里实现的目标。通常,静态成员可能不是最好的想法,所以也许可以考虑做其他事情。

总而言之,如果集合不是静态成员,那么你仍然会遇到一个概念问题:静态类型的要点是在编译时获得类型信息。当编译为JavaScript时,根本不会输入该集合,并且它不会强制执行编译时仍然存在的类型信息。

这就是为什么你根本不能使用仅在运行时存在的类型信息。并且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>将有一个match (d {Name:'D'})-[:TO]-(b) with collect(distinct b.Name) as neighbors match (n)-[r:TO]->(m) where not (n.Name in (neighbors+'D')) and not (m.Name in (neighbors+'D')) return n, r, m; match (d {Name:'D'})-[:TO]-(b)-[:TO]->(leaf) where not((leaf)-->()) return (leaf); match (d {Name:'D'})-[:TO]-(b)<-[:TO]-(root) where not((root)<--()) return (root) 成员,可在编译时使用。