Сравнение типов дженериков Typescript не работает

У меня проблемы со сравнением дочернего элемента с универсальным типом T и возвратом массива только этих типизированных дочерних элементов. Логика проста, у меня есть массив дочерних элементов с разными элементами, унаследованными от типа Test. Мне нужно только подмножество особых детей. Кажется, теперь я могу найти решение для сравнения универсального типа T с дочерними элементами.

В результате возникает ошибка TS2693: «T» относится только к типу, но здесь используется как значение.

Пробовал с instanceof, typeof, Object.getPrototypeOf, ничего не работает.

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

person marius    schedule 03.07.2020    source источник


Ответы (1)


Проблема в том, что вся информация о типах фактически удаляется после переноса Typescript в 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

Как видите, JavaScript не знает, что такое ваш T, поэтому он не может проверить его экземпляр. Возможно, вы можете просто заменить child instanceof T на child instanceof Test, если это вам подходит. В противном случае потребуются некоторые дополнительные проверки во время выполнения (например, утиный ввод). Вы можете использовать определяемые пользователем типы защиты (https://basarat.gitbook.io/typescript/type-system/typeguard#user-defined-type-guards).

person Amadare42    schedule 03.07.2020