Типовые параметры Typescript, расширяющие исключительные объединения - PullRequest
0 голосов
/ 22 октября 2018

В TypeScript есть способ определить универсальный параметр, который расширяет только одно значение типа объединения?

Например, если я объявляю тип объединения следующим образом:

type Any = "A" | "B"

тогда, если я использую тип в определении функции следующим образом:

const fn = <T extends Any>(arg: T[]) => {}

, тогда аргумент args может быть массивом, который содержит значения как "A", так и "B".«;например, это будет допустимо:

let x = fn(["A", "B"])

, что противоречит самой цели использования универсального параметра в определении функции (т. е. ограничить значения в массиве аргументов args толькоодин конкретный тип)

Конечно, я мог бы определить функцию следующим образом:

const fn = (arg: "A"[] | "B"[]) => {}

Но если число типов компонентов в объединении велико, это может быть нецелесообразно

1 Ответ

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

Существует предложенная функция, которая позволит вам сообщить компилятору, что T - это один из нескольких типов, а не их объединение.Проблема помечена как обсуждаемая, поэтому, возможно, добавьте к ней +1.

Тем временем мы можем заставить компилятор выдать нам ошибку, если T является объединением, используяусловные типы:

type Any = "A" | "B"

type UnionToIntersection<U> = 
  (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
type NoUnion<T, TError> = [T] extends [UnionToIntersection<T>] ? {} : TError

type d = NoUnion<Any, ""> 
const fn = <T extends Any>(arg: T[] & NoUnion<T, "Must be A or B not a union">) => { }

fn(null as "A"[])
fn(null as "B"[])
fn(null as ("A" | "B")[]) //error Type 'Any[]' is not assignable to type '"Must be A or B not a union"'
...