Typescript generics type comparison not working

58 Views Asked by At

I have troubles comparing an element "child" with an generic type T and returning an array of only these typed children.

The logic is easy, I have an array of children with different elements all inheriting from type "Test". I only want a subset of "special" children.

I seem to now be able to find a solution for comparing the generic type T with the children in any way.

The resulting error is

TS2693: 'T' only refers to a type, but is being used as a value here

I tried it with instanceof, typeof, Object.getPrototypeOf, nothing is working.

 public getChildrenByType<T extends Test>(): T[] {
        const output:T[] = [];
        for(const child of this.children) {
            if(child instanceof T) {
                output.push(child);
            }
        }
    }
    return output;
}
1

There are 1 best solutions below

0
Amadare42 On

The problem is that all type information is actually stripped after transpiling Typescript into JavaScript. You can check it quite easily just by observing result of transpilation in Typescript playground: https://www.typescriptlang.org/play/index.html#code/MYGwhgzhAEAqCmEAu0De0C+AoLAzArgHbBICWA9odAObxIDCAFqSACYBO8hAQgJ6y8ADvAA8saPAAeSLqxgJkAPgAUASgBccANoBdNFmiGjh4JWTRy+JIKvrYu6AF5ougNwHjR3OXbLThc2BmNgtcaCCWDi5VfU846FJcP2DWBICkMGJ4cjDYGNQPePjLaysAOhsIRmTI1Xci42wipqMWw04kfHYqEpskdwwgA

As you can see, JavaScript does not know what your T is, so it cannot check it's an instance. You can probably just replace child instanceof T with child instanceof Test if that suits your needs. Otherwise, some additional runtime checks (e.g. duck-typing) will be required. You can use User Defined Type Guards (https://basarat.gitbook.io/typescript/type-system/typeguard#user-defined-type-guards).