简体   繁体   English

如何基于泛型类型定义抽象属性

[英]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 中定义属性的类型并在子类中初始化它。

link to playground 链接到游乐场


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.我希望使用ArrayMap初始化子类中的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>();
}

updated playground 更新的游乐场

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM