Typescript generics type comparison not working

48 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
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).