扩展排他联合的打字稿通用参数

时间:2018-10-22 09:28:29

标签: javascript typescript generics pattern-matching union

在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 :(得分:1)

有一个建议的功能,可以让您告诉编译器T是许多类型之一,而不是它们的并集。 issue被标记为正在讨论中,因此可以为其添加+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"'