为什么 Typescript 无法推断 RxJs 流中的元组返回类型?

phi*_*2mj 2 generics types rxjs typescript angular

在组合可观察流时,从映射函数返回的元组被编译器推断为联合而不是元组。

例如:

import { Component } from '@angular/core';
import { from } from 'rxjs';
import { map, tap } from 'rxjs/operators';

export class MyType {
  constructor(private name: string) {}
}

@Component({
  selector: 'my-app',
  template: ''
})
export class AppComponent {
  observable$ = from([new MyType('obj1'), new MyType('obj2')]).pipe(
    map((value, index) => [value, index]),
    tap(([value, index]) => console.log(value, index))
  ).subscribe();
}
Run Code Online (Sandbox Code Playgroud)

在stackblitz上查看一下,如果您将鼠标悬停在 中 的函数参数上value或中,它们都会被推断出何时应该理解和。indextapnumber | MyTypevalue: MyTypeindex: number

如果我通过填写泛型来注释地图:map<MyType, [MyType, number]>(...那么输入是正确的。

这是预期的行为吗?打字稿不应该理解该元组而不必显式传递类型吗?

我在本地使用 rxjs @ 6.4.0 和 typescript @ 3.8.3,但 stackblitz 有更新的版本,并且仍然呈现此行为。

Les*_*iak 6

在您的map函数中,您返回一个数组,而不是元组。

您可以使用as const强制元组类型:

export class AppComponent {
  observable$ = from([new MyType('obj1'), new MyType('obj2')]).pipe(
    map((value, index) => [value, index] as const),
    tap(([value, index]) => console.log(value, index))
  ).subscribe();
}
Run Code Online (Sandbox Code Playgroud)

请参阅元组类型

带有断言的数组文字const将被推断为readonly元组类型