TS2339 - 明显有效的 TS 文件中的“类型上不存在属性"错误 [英] TS2339 - 'Property doesn't exist on type' error in an apparently valid TS file
问题描述
我有以下类型声明:
type Root = { r: string };
type A = { a: string };
type B = { b: string };
type Main = Root & (A | B);
由于 Main
等价于 {r: string, a: string} |{r: string, b: string}
,这是有效的:
Since Main
is equivalent to {r: string, a: string} | {r: string, b: string}
, this works:
const main: Main = {
r: 'r',
a: 'a'
}
这里没有惊喜.但是,这会引发以下错误:
No surprises here. However, this throws the following error:
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' */
}
我知道 .a
不存在于 Root &B
,但它存在于 Root &A
,所以它必须存在于 (Root & A) |(Root & B)
等价于 Main
吧?
I do understand that .a
doesn't exist on Root & B
, but it exists on Root & A
, so it must exists on (Root & A) | (Root & B)
which is equivalent to Main
, right?
这是一个错误,还是我遗漏了什么?
Is it a bug, or am I missing something?
推荐答案
Main
等同于 (Root & A) | 你说得对(Root & B)
你对联合类型 (|
) 的解释是错误的.联合类型意味着您可以将联合中的任何一种类型分配给 main
(所以要么 (Root & A)
要么 (Root & B)
),但您只能访问联合成员的公共属性.在这种情况下,公共成员只是 r
.由于 main
可以是 (Root & A)
或 (Root & B)
,a
可能不是存在于 main
上,所以 typescript 阻止了这样的访问.
You are right about Main
being equivalent to (Root & A) | (Root & B)
you are wrong about the interpretation of union types (|
). A union type means you can assign either type in the union to main
( so either (Root & A)
or (Root & B)
), but you can only access common properties of the union members. In this case the common member is only r
. Since main
ca be either (Root & A)
or (Root & B)
, a
might not exist on main
, so typescript prevents such an access.
要使用仅存在于联合中的一种类型的成员,您需要一个类型保护.在这种情况下,in
类型保护将最有效:
To use the members that only exist on one type in the union you need a type guard. In this case an in
type-guard will work best:
const func : (main: Main) => void = main => {
if ('a' in main) {
main.a
} else {
main.b
}
}
您可以在此处
这篇关于TS2339 - 明显有效的 TS 文件中的“类型上不存在属性"错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!