推断TypeScript中类型防护的并集类型

时间:2018-09-08 16:26:07

标签: typescript

TypeScript似乎在推断类型保护的并集类型方面存在问题。例如,考虑一个将带有以下签名的类型保护数组组合的函数

function combine<T>(guards: ((x: any) => x is T)[]): (x: any) => x is T

并考虑以下{@ {1}}和A具有不同属性的类型保护

B

现在,我希望function isA(x: any): x is A function isB(x: any): x is B 可以工作并且具有推断的类型combine([isA, isB]),但我收到一条错误消息,指出类型(x: any) => x is A | B的参数不能分配给类型{{ 1}},这意味着((x: any) => x is A | (x: any) => x is B)[]被推断为(x: any) => x is A而不是T

明确指定A时,即A | B,它可以正常工作。有没有一种方法可以更改T的签名,以便可以推断出该签名?

1 个答案:

答案 0 :(得分:3)

您可以使用类型参数来表示整个函数,而不仅仅是保护类型。这使编译器可以推断保护函数的并集。然后,我们可以使用条件类型来提取受保护类型的并集:

type GuardType<T> = T extends (o: any) => o is infer U ? U : never

class A { q: any }
class B { p: any }
declare function isA(x: any): x is A
declare function isB(x: any): x is B

declare function combine<T extends ((x: any) => x is any)>(guards: T[]): (x: any) => x is GuardType<T>

let isAB = combine([isA, isB]); // (x:any) => x is A|B
相关问题