switchMap(innerHello => {
return of(world).pipe(map(innerWorld => [innerHello, innerWorld]));
}),
map(([hello, world]) => {
console.log('result', hello.hello, world.world);
})
为什么,在使用switchMap
运算符时,我会警告说property hello does not exist on type Hello | World
。
我从内部映射返回一个数组,所以为什么要期望并集呢?
答案 0 :(得分:3)
[innerHello, innerWorld]
的推断类型为Array<Hello|World>
,您不能访问两个类型都不相同的属性。
您可以做的是将数组显式键入
map(([hello, world]: [Hello, World]) => {
console.log('result', hello.hello, world.world);
})
答案 1 :(得分:1)
正如在另一个答案中已经提到的那样,打字稿会以联合类型World|Hello
来推断数组中对象的类型,因此您将无法在两者之间访问非常见属性。类而不使用某种形式的 type guard 。
@David提供的答案很好,但是它迫使您强制转换数组的类型。
请注意,如果您更改了在数组创建过程中将对象添加到数组的顺序,则不会出现任何编译器警告。 (例如:从[innerHello, innerWorld]
到[innerWorld, innerHello]
)。
另一种方法来保持类型检查而不进行类型转换并更好地支持编译器,这是将属性收集到一个普通对象中,然后对其进行解构:
const helloVal: Hello = {
hello: 'hello'
};
const worldVal: World = {
world: 'world'
};
const source = of(helloVal).pipe(
switchMap(hello => of(worldVal).pipe(map(world => ({ hello, world }))))
);
source.subscribe(({ hello, world }) => {
console.log('result', hello.hello, world.world);
});
在这种情况下,hello
回调中可以正确推断出world
和subscribe
的类型。 请注意,在这种情况下,您会“绑定”到用于创建结果对象的属性名称,而不是其顺序。
正在运行的演示in this blitz
答案 2 :(得分:-1)
我从内部映射返回一个数组,所以为什么要期望并集呢?
这就是您明确告诉它的期望:
console.log('result', hello.hello, world.world);
因此,“访问hello
对象的hello
属性(或:数组的第0个元素),并访问world
对象的world
属性” 。
将其更改为console.log('result', hello, world)
。