问题描述
我收到以下错误:
type Union = { type: "1"; foo: string } | { type: "2"; bar: number };
function doSomething = (object: Union) => {
const { foo } = object
// ^ TS2339: Property 'foo' does not exist on type 'Union'.
console.log(object.bar)
// ^ TS2339: Property 'bar' does not exist on type 'Union'.
}
预期结果:
typeof foo === string | undefined
typeof bar === number | undefined
如何在没有明确类型保护的情况下访问属性,例如:
const foo = o.type === 1 ? o.foo : undefined
const bar = o.type === 2 ? o.bar : undefined
这对我来说不是一个真正的选择,因为我正在处理大型联合,其中许多对象上可能存在也可能不存在目标属性,这将是一团糟。
我还有哪些选择?
解决方法
这里的问题是,因为 B 没有声明 a 属性,所以它可能在运行时具有任何可能类型的 a 属性(因为您可以将具有任何属性集的对象分配给 B,只要它具有字符串类型的 ab 属性)。你可以让它在 B 中显式声明一个 a: undefined 属性(从而确保 B 不会有一些随机的属性):
type A = { a: string; }
type B = { b: string; a: undefined }
type AorB = A | B;
declare const AorB: AorB;
if (AorB.a) {
// Ok
}
,
这种行为有点道理,因为 TS 不知道它正在处理来自 Union 的哪个对象,并且在某些情况下该属性不存在。
我不确定这是否是您要找的东西,但您可以尝试类似的方法
type Union = { type: "1"; foo: string } | { type: "2"; bar: number };
function doSomething = (object: Union) => {
if ('foo' in object) {
const { foo } = object
}
if ('bar' in object) {
console.log(object.bar)
}
}