javascripttypescripttuplesvariadic-tuple-types

typescript tuple in class heritance, lost types


how i can override a class array with tuple and add native instance in index and keep the types ?

how i can make this valid, what can be the correct syntax ?

playground: playground

class Base {
    protected children?:Base[]
}
class Containers extends Base {
    protected override children:Array<Containers|Primitives>; 
}

class Primitives extends Base {
}

class A extends Containers {
 // so children should automaticly someting like : [A,A,B,...Containers|Primitives] ?
    protected override children:[A,A,B]
    init(){
        const i0 = this.children[0];
        const i1 = this.children[1]; 
        const i2 = this.children[2]; 
        const i3 = this.children[3]; // should Containers|Primitives|undefined because extends Containers ?
    }

}
class B extends Containers {

}

So in this code A can have native instance in children index, where i use getter . But ...rest of children should auto herite parent Containers|Primitives no ?

Also this is weird , if i remove type, everything became instance A ?!! enter image description here

EDIT: I see i can write like this ! protected override children:[A,...Array<Containers|Primitives>] But i repeat code from parent class, is there a good way to avoid repeat ?


Solution

  • class Base {
        protected children?: Base[]
    }
    class Containers extends Base {
        // let say, container entity can have childrens (Containers|Primitives)
        protected override children: Array<Containers | Primitives> = [];
    }
    
    class Primitives extends Base {
    }
    
    class A extends Containers {
        // Let say A have some native instance in children [A,A,B,...Containers|Primitives]
        protected override children: [A, A, B, ...Containers[] | Primitives[]] = [new A(), new A(), new B()];
        init() {
            const i0 = this.children[0];
            const i1 = this.children[1];
            const i2 = this.children[2];
            const i3 = this.children[3]; // // Primitives | Containers
        }
    
    }
    class B extends Containers {
    
    }
    

    You need to use spread syntax

    [A,A,B,...Containers|Primitives] does not compile because you are allowed to use ... only with arrays

    Playground

    children is referenced directly or indirectly in its own initializer, so explicit type annotation is required