Разобрать тип объединения TypeScript на определенные типы - PullRequest
0 голосов
/ 22 октября 2018

Интересно, можно ли «разбить» типы объединения на конкретные подтипы в TypeScript.Это код, который я пытался использовать, должно быть очевидно, чего я пытаюсь добиться из фрагмента:

type SplitType<T> =
T extends (infer A)|(infer B)
? Something<A, B>
: T;

В этом примере Something<A, B> может быть [A, B] или совершенно другого типа,Это будет означать, что SplitType<string> будет просто выводить string, но SplitType<number|string> будет означать [number, string].

Возможно ли что-то подобное в TypeScript?А если нет, то есть ли функция, которая позволит это в будущем (например, типы переменных )?

1 Ответ

0 голосов
/ 22 октября 2018

Для фиксированного максимального числа членов объединения мы можем извлечь члены объединения в одном порядке, определяемом реализацией, создав пересечение сигнатур вызовов и затем сопоставив его с типом с несколькими сигнатурами вызовов.Эта версия работает только при включенном strictFunctionTypes.

// https://stackoverflow.com/a/50375286
type UnionToIntersection<U> = 
  (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never

type UnionToFunctions<U> =
    U extends unknown ? (k: U) => void : never;

type IntersectionOfFunctionsToType<F> =
    F extends { (a: infer A): void; (b: infer B): void; (c: infer C): void; } ? [A, B, C] :
    F extends { (a: infer A): void; (b: infer B): void; } ? [A, B] :
    F extends { (a: infer A): void } ? [A] :
    never;

type SplitType<T> =
    IntersectionOfFunctionsToType<UnionToIntersection<UnionToFunctions<T>>>;

type Test1 = SplitType<number>;                    // [number]
type Test2 = SplitType<number | string>;           // [string, number]
type Test3 = SplitType<number | string | symbol>;  // [string, number, symbol]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...