内部映射switchMap时,rxjs期望联合类型

时间:2019-04-02 10:14:18

标签: typescript rxjs

Demo here

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
我从内部映射返回一个数组,所以为什么要期望并集呢?

3 个答案:

答案 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回调中可以正确推断出worldsubscribe的类型。 请注意,在这种情况下,您会“绑定”到用于创建结果对象的属性名称,而不是其顺序

正在运行的演示in this blitz

答案 2 :(得分:-1)

  

我从内部映射返回一个数组,所以为什么要期望并集呢?

这就是您明确告诉它的期望:

  console.log('result', hello.hello, world.world);

因此,“访问hello对象的hello属性(或:数组的第0个元素),并访问world对象的world属性” 。

将其更改为console.log('result', hello, world)