部分<Observer<unknown>> 尝试在订阅中键入下一个值时出错

Partial<Observer<unknown>> error when trying to type next value in subscribe

我创建了一个 rxjs 流,里面有几个运算符,稍后我会向您展示,但首先我想描述一下错误

我有以下(简体)

return fromEvent(....).pipe(
  ....
).subscribe((output: IOutput<IData>) => ....); // <-- error

CODE

不幸的是,stackblitz 演示没有给出任何错误,它只发生在我的 IDE 中。我得到的错误是

No overload matches this call.
  Overload 1 of 3, '(observer?: Partial<Observer<unknown>> | undefined): Subscription', gave the following error.
    Type '(output: IOutput<IData>) => void' has no properties in common with type 'Partial<Observer<unknown>>'.
  Overload 2 of 3, '(next: (value: unknown) => void): Subscription', gave the following error.
    Argument of type '(output: IOutput<IData>) => void' is not assignable to parameter of type '(value: unknown) => void'.
      Types of parameters 'output' and 'value' are incompatible.
        Type 'unknown' is not assignable to type 'IOutput<IData>'.
  Overload 3 of 3, '(next?: ((value: unknown) => void) | null | undefined, error?: ((error: any) => void) | null | undefined, complete?: (() => void) | null | undefined): Subscription', gave the following error.
    Argument of type '(output: IOutput<IData>) => void' is not assignable to parameter of type '(value: unknown) => void'.
      Types of parameters 'output' and 'value' are incompatible.
        Type 'unknown' is not assignable to type 'IOutput<IData>'.ts(2769)

奇怪的是,如果我注释掉其中一个运算符,我可以让错误消失

这里我注释掉了tap运算符,但是当我注释掉那个filter运算符时,同样的事情发生了。

解决此问题的另一种方法是将 subscribe 重写为

 .subscribe((output)  => observer.next(output as IOutput<IData>));

但无论我做什么,我都不知道这里发生了什么。比如注释掉那个tap运算符怎么解决错误。

如有任何帮助,我们将不胜感激!

由于 tsconfig 设置(可能 strictFunctionTypes),该问题未出现在 StackBlitz 上,但您可以在 TypeScript playground 中重现它。

问题是 rxjs 类型定义仅对最多 10 个参数进行类型 pipe 重载。超过 10,结果类型变为 Observable<unknown>.

达到十个运算符后,您可以通过将管道链接在一起来修复它:

const sub = fromEvent<Event>(document, 'click', { capture: true })
  .pipe(
    xPreventPropagation$<Event>(),
    ..
    tap((update) => console.log('test3')))
  .pipe(
    map<IData, IOutput<IData>>((update: IData) => ({
      result: update,
    }))
  )
  .subscribe((output: IOutput<IData>) => observer.next(output));

TypeScript playground