Typescript rxjs在内部映射switchMap时需要union类型

Typescript rxjs在内部映射switchMap时需要union类型,typescript,rxjs,Typescript,Rxjs,为什么在使用switchMap操作符时,我会收到一条警告,提示键入hello | World时不存在属性hello 我从内部映射返回一个数组,那么为什么它需要一个并集呢 我从内部映射返回一个数组,那么为什么它需要一个并集呢 这就是你明确告诉它的期望: console.log('result', hello.hello, world.world); 因此,“访问hello对象(或数组的第0个元素)的hello属性,并访问world对象的world属性” 将其更改为console.log('r

为什么在使用
switchMap
操作符时,我会收到一条警告,提示键入hello | World时不存在
属性hello
我从内部映射返回一个数组,那么为什么它需要一个并集呢

我从内部映射返回一个数组,那么为什么它需要一个并集呢

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

  console.log('result', hello.hello, world.world);
因此,“访问
hello
对象(或数组的第0个元素)的
hello
属性,并访问
world
对象的
world
属性”


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

[innerHello,innerWorld]
的推断类型为
Array
您无法访问两种类型中都不存在的属性

您可以做的是显式地将数组键入

map(([hello, world]: [Hello, World]) => {
  console.log('result', hello.hello, world.world);
})

正如在另一个答案中已经提到的,typescript将数组中对象的类型推断为union类型
World | Hello
,因此如果不使用某种形式的类型保护,您将无法访问类之间的非公共属性

@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);
});
在这种情况下,在
subscribe
回调中正确推断出
hello
world
的类型请注意,在本例中,您“绑定”到用于创建结果对象的属性名称,而不是它们的顺序


工作演示

它似乎在您共享的演示链接中工作,但在hello和world上有警告(弯曲的红线)。您需要指定参数类型:
map(([hello,world]:[hello,world])
你是什么意思?警告告诉我hello可以是hello或World类型,但我从未明确说过。它从
innerHello
的类型和
World
的类型(返回(世界)
中的类型)推断出类型。是的,我(错误地)认为[hello,World]会被推断出来。不是[Hello | World]。谢谢,正如我在另一篇评论中所说的,我认为[Hello,World]应该是这样推断的,而不是[Hello | World]。谢谢。
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);
});