Распространение универсального типа через объединение

#typescript #generics #types #union

#typescript #универсальные типы #типы #объединение

Вопрос:

Есть ли способ в TS «распространять» универсальный тип через объединение?

 type Container<A> = { value: A };

type Containers<string | number> = Container<string> | Container<number>
  

(Предполагая, что мы знаем из контекста, когда применять Containers vs Container )

Ответ №1:

удивительно, но вывод типа сделал бы это за вас:

 type Container<T> = { value: T }

type Containers<T> = T extends infer A ? Container<A> : never;
  

компилятор достаточно умен, чтобы разделить их все:

 type C = Containers<string | number | {x: number} | {z: string} | boolean>
  

тип C расширяется следующим образом:

 type C = Container<string> | 
         Container<number> | 
         Container<false> | 
         Container<true> | 
         Container<{
           x: number;
         }> | 
         Container<{
           z: string;
         }>
  

ts-игровая площадка

Комментарии:

1. Потрясающе! Это именно то, что я искал, большое спасибо 🙏

Ответ №2:

Учитывая ваш пример кода, я думаю, вы хотите определить универсальный тип, который ограничен объединением типов. Один из них должен соответствовать вашим требованиям.

 type Container<T> = { value: T };
type ContainerA = Container<string | number>;
type ContainerB = Container<string> | Container<number>
type ContainerC<T extends string | number> = Container<T>;
  

Обратите также внимание, что Распространение — это синтаксическое правило в JavaScript. Его использование в вашем вопросе сбивает с толку.

Комментарии:

1. ответ @leetwinski лучше соответствует моим потребностям, но спасибо! Вы правы, я изменю его на «распространять» 👍 Приветствия