TypeScript扩展了关键字,弄乱了类型推断

时间:2018-09-18 09:23:06

标签: typescript

为什么以下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"之后,cA。为什么不呢?

以下变体似乎可以正常工作。

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))

1 个答案:

答案 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);
}

Playground link