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的类型?
答案 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)
成员,可在编译时使用。