Получить тип параметра из универсального на TypeScript

Предположим, у меня есть следующий фрагмент кода:

interface Generic <S, T> {
    _?: [S, T];
    id: string;
    ...
}

interface A {}
interface B {}
interface C {}
interface D {}

type t1 = Generic<A, B>;
type t2 = Generic<B, C>;

Это код, который я не могу изменить (из другого пакета). Мой вопрос: есть ли способ программно узнать, что такое S и T для данного типа (например, t1, t2)?

У меня есть сильное подозрение, что, поскольку эта информация теряется после компиляции, я никогда не смогу выяснить, что такое S и T во время выполнения. Хуже того, я не смогу просмотреть детали t1 и t2 (как и в предыдущем вопросе).

Однако, поскольку я очень новичок в TypeScript, мне интересно, если я просто не знал, как правильно спросить, и в Интернете действительно есть ответ для меня.

Итак, возможно ли это? Как?


person jumattos    schedule 19.03.2019    source источник
comment
Обратите внимание, что t1 и t2 — это абсолютно одинаковые типы, поскольку A, B, C и D — это идентичные пустые интерфейсы. Система типов TypeScript является структурной, а не номинальной. Два типа эквивалентны тогда и только тогда, когда они имеют одинаковую структуру, а не одно и то же имя. Это приведет к странному поведению, поэтому я бы посоветовал (даже в демонстрационных типах, подобных приведенным выше), добавить некоторые разные свойства, чтобы различать их.   -  person jcalz    schedule 20.03.2019


Ответы (1)


Вы правы в том, что, поскольку типы TypeScript стираются во время выполнения, вы не можете получить к ним доступ. Однако вы можете получить доступ к типам общих параметров во время компиляции, используя условные типы:

type FirstOfGeneric<G> = G extends Generic<infer F, any> ? F : never;
type SecondOfGeneric<G> = G extends Generic<any, infer S> ? S : never;

// type t1_f = A
type t1_f = FirstOfGeneric<t1>;
// type t1_s = B
type t1_s = SecondOfGeneric<t1>;

Затем вы можете использовать стандартные функции TS, такие как typeguards и приведение к действию экземпляров среды выполнения t1_f и t1_s,

person y2bd    schedule 20.03.2019