首页 > 解决方案 > 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",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))

标签: typescript

解决方案


类型保护将作用于联合类型的参数,它不适用于扩展联合的泛型类型参数。此问题记录在案。这个问题是开放的,可能会在以后得到解决。

此问题的一种可能解决方法是使用您的非通用版本,对于您的简单示例,它的工作原理相同。

如果您的签名更复杂,并且您在某些其他能力中使用泛型类型(例如在某些条件类型中,或创建其他参数或参数与返回类型之间的关系),您可以使用具有多个签名的函数,公共泛型签名和非通用实现签名:

function c<C extends A | B>(c: C): void
function c(c: A | B): void {
    return c.kind == "a" ? a(c) : b(c);
}

游乐场链接


推荐阅读