为什么以下TypeScript代码无效?
type A = { kind: "a" }
type B = { kind: "b" }
const a = (a: A): void => undefined
const b = (b: B): void => undefined
const c = <C extends A | B>(c: C): void => (c.kind == "a" ? a(c) : b(c))
TypeScript似乎无法确定在c.kind == "a"
之后,c
是A
。为什么不呢?
以下变体似乎可以正常工作。
type A = { kind: "a" }
type B = { kind: "b" }
type C = A | B
const a = (a: A): void => undefined
const b = (b: B): void => undefined
const c = (c: C): void => (c.kind == "a" ? a(c) : b(c))
答案 0 :(得分:2)
Typeguard将对联合类型的参数起作用,而对扩展联合的通用类型参数不起作用。 issue中对此进行了记录。该问题是公开的,以后可能会解决。
此问题的一种可能的解决方法是使用您的非通用版本,对于您的简单示例,该版本将完全相同。
如果签名更加复杂,并且您以其他身份使用通用类型(例如,以某些条件类型使用,或者在其他一个或多个参数与返回类型之间创建关系),则可以使用具有多个签名的函数,公共通用签名和非通用实现签名:
function c<C extends A | B>(c: C): void
function c(c: A | B): void {
return c.kind == "a" ? a(c) : b(c);
}