TS2339 - 明显有效的 TS 文件中的“类型上不存在属性”错误

Nin*_*liu 3 typescript

我有以下类型声明:

type Root = { r: string };
type A = { a: string };
type B = { b: string };
type Main = Root & (A | B);
Run Code Online (Sandbox Code Playgroud)

由于Main等效于{r: string, a: string} | {r: string, b: string},因此有效:

const main: Main = {
    r: 'r',
    a: 'a'
}
Run Code Online (Sandbox Code Playgroud)

这里没有惊喜。但是,这会引发以下错误:

const func : (main: Main) => void = main => {
    main.a
    /*   ^
    * [TS2339]
    * Property 'a' doesn't exist on type 'Main'.
    *   Property 'a' doesn't exist on type 'Root & B' */
}
Run Code Online (Sandbox Code Playgroud)

我明白.a不存在于 上Root & B,但存在于 上Root & A,所以它必须存在于 上(Root & A) | (Root & B), 与 等效Main,对吗?

这是一个错误,还是我错过了什么?

Tit*_*mir 5

你对Main等价于(Root & A) | (Root & B)你对联合类型(|)的解释是错误的。甲联合类型的装置可以在联合任一类型分配给main(因此无论(Root & A)(Root & B)),但只能访问联盟成员的共同性质。在这种情况下,公共成员仅为r. 由于mainCA是任一(Root & A)(Root & B)a可能不存在上main,所以防止了打字原稿这样的访问。

要使用仅存在于联合中的一种类型的成员,您需要一个类型保护。在这种情况下,in类型保护将最有效:

const func : (main: Main) => void = main => {
    if ('a' in main) {
        main.a
    } else {
        main.b
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在此处阅读有关类型保护的更多信息