RxJS如何将combineLatest与具有多个值的startWith一起使用?

sta*_*orn 1 rxjs angular

combineLatest我对使用操作员startWith有疑问

下面的代码有效

const data_1$ = new Subject<string>();
const data_2$ = new Subject<number>();

viewModel$ = combineLatest([data_1$, data_2$])
   .pipe(map([data_1, data_2]) => {
      return { data_1, data_2 };
   })

Run Code Online (Sandbox Code Playgroud)

但是现在如果我想使用startWith运算符

const data_1$ = new Subject<string>();
const data_2$ = new Subject<number>();

viewModel$ = combineLatest([data_1$, data_2$])
   .pipe(
      startWith(["hello", 1]),
      map([data_1, data_2]) => {
         return { data_1, data_2 };
      })

Run Code Online (Sandbox Code Playgroud)

map部分将推断出data_1data_2可以是string | number。我可以将其推断为第一个不使用的示例吗startWith?我知道BehaviorSubject它可以用来代替,startWith但就我而言,我需要使用 startWith。

IDK*_*eal 5

官方文档开始,startWith的输入如下:

startWith<T, D>(...values: D[]): OperatorFunction<T, T | D>
Run Code Online (Sandbox Code Playgroud)

就您而言,您希望确保startWith仅返回 类型的内容[string, number]

出现此问题的原因是,当您提供数组时,['hello',1]它会将类型视为(string|number)[]. 这是因为在泛型声明中,仅D[]提供了一种类型。['hello',1]这就是为什么它认为to的类型(string|number)[]是适合的D[]

为了解决这个问题,您可以使用泛型显式提供类型:

startWith<[string, number]>(['hello', 1])
Run Code Online (Sandbox Code Playgroud)

那么问题来了,为什么map当前会推断出参数类型呢?那么这个问题的答案也在map 的官方输入中:

map<T, R>(project: (value: T, index: number) => R, thisArg?: any): OperatorFunction<T, R>
Run Code Online (Sandbox Code Playgroud)

map的例子中,它从提供的 value 推断出类型T。由于不需要匹配任何数组转换,因此[string, number]使用 的值来代替。