[英]How to define abstract property based on generic type
What I'm trying to do is to define type of a property in abstract class and initialize it in child classes.我要做的是在抽象 class 中定义属性的类型并在子类中初始化它。
I have type that returns different type based on whether passed argument is an array:我有根据传递的参数是否为数组返回不同类型的类型:
type ArrayElement<T> = T extends (infer R)[] ? R : never;
type Children<T> = T extends unknown[] ? Wrapper<ArrayElement<T>>[] : Map<string, Wrapper>;
The wrapper class defines its children property as type Children<T>
:包装器 class 将其 children 属性定义为Children<T>
类型:
abstract class Wrapper<T = any> {
// need access to children in this class.
abstract children: Children<T>
getChildren(): Wrapper[] {
return Array.from(this.children.values())
}
}
I would expect to initialize children
property in child classes with either Array
or a Map
, but even with correct generic passed to Wrapper
it doesn't work.我希望使用Array
或Map
初始化子类中的children
属性,但即使将正确的泛型传递给Wrapper
它也不起作用。
class WrapperArray<T extends unknown[]> extends Wrapper<T> {
// Property 'children' in type 'WrapperArray<T>' is not assignable to the same
// property in base type 'Wrapper<T>'.
// Type 'Wrapper<ArrayElement<T>>[]' is not assignable to type 'Children<T>'.(2416)
children = [] as Wrapper<ArrayElement<T>>[];
}
class WrapperGroup<T> extends Wrapper<T> {
// Property 'children' in type 'WrapperGroup<T>' is not assignable to the same
// property in base type 'Wrapper<T>'.
// Type 'Map<string, Wrapper<any>>' is not assignable to type 'Children<T>'.(2416)
children = new Map<string, Wrapper>();
}
Alright, so solution was easier than I thought.好吧,所以解决方案比我想象的要容易。 All I had to do, is to cast child class children property to Children
type with correct generic:我所要做的就是将子 class 子属性转换为具有正确泛型的Children
类型:
abstract class Wrapper<T = any> {
abstract children: Children<T>;
getChildren(): Wrapper[] {
return Array.from(this.children.values());
}
}
class WrapperArray<T extends unknown[]> extends Wrapper<T> {
children = [] as Wrapper<ArrayElement<T>>[] as Children<T>l;
test() {
// works
this.children.map(c => c)
}
}
// Not so sure if {} is enough, because it allows arrays tho
class WrapperGroup<T extends {}> extends Wrapper<T> {
children = new Map<string, Wrapper>() as Children<T>;
test() {
// works
this.children.get('test')
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.