为什么打字稿不能在 RxJs 流中推断元组 return 类型?
Why can't typescript infer tuple return type in RxJs stream?
在组成可观察流时,编译器将从 map 函数返回的元组推断为联合而不是元组。
例如:
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();
}
在 stackblitz 上查看,如果您将鼠标悬停在 tap
中函数参数中的 value
或 index
上,它们都会被推断为 number | MyType
当它应该理解为 value: MyType
和 index: number
.
如果我通过填写泛型来注释地图:map<MyType, [MyType, number]>(...
那么输入是正确的。
这是预期的行为吗?打字稿不应该在不必显式传递类型的情况下理解该元组吗?
我在本地使用 rxjs @ 6.4.0 和 typescript @ 3.8.3,但 stackblitz 有更新的版本并且仍然出现这种行为。
在您的 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();
}
参见Tuple Types:
array literals with const
assertions will be inferred with readonly
tuple types
在组成可观察流时,编译器将从 map 函数返回的元组推断为联合而不是元组。
例如:
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();
}
在 stackblitz 上查看,如果您将鼠标悬停在 tap
中函数参数中的 value
或 index
上,它们都会被推断为 number | MyType
当它应该理解为 value: MyType
和 index: number
.
如果我通过填写泛型来注释地图:map<MyType, [MyType, number]>(...
那么输入是正确的。
这是预期的行为吗?打字稿不应该在不必显式传递类型的情况下理解该元组吗?
我在本地使用 rxjs @ 6.4.0 和 typescript @ 3.8.3,但 stackblitz 有更新的版本并且仍然出现这种行为。
在您的 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();
}
参见Tuple Types:
array literals with
const
assertions will be inferred withreadonly
tuple types