VSCode TypeScript rxjs map() 运算符在足够的重复后丢失类型

VSCode TypeScript rxjs map() operator loses type after enough repetitions

我的问题是;是什么导致 vscode 失去对类型的跟踪,以及是否有任何方法可以扩展它的功能。其次,我们将不胜感激任何可能的解决方法。

我进行了一些谷歌搜索,发现了一些与无限类型递归相关的问题被放弃了,但我不确定这是否落在了那条船上。如果是的话,我认为这个实例非常有趣,因为 Rxjs 是一个广泛使用的库,并且这个问题可以在给定管道中仅调用 9 次 map 后触发。

https://github.com/microsoft/TypeScript/issues/35533
https://github.com/microsoft/TypeScript/issues/29511

请参阅下面的简单代码片段,该代码片段重现了 vscode 中的问题。

import { Subject } from 'rxjs';
import { map } from 'rxjs/operators';

const test = new Subject<string>();

test.pipe(
  map(msg => msg),
  map(msg => msg),
  map(msg => msg),
  map(msg => msg),
  map(msg => msg),
  map(msg => msg),
  map(msg => msg),
  map(msg => msg),
  map(msg => msg),
  map(msg => msg) // <---- type is lost here, msg becomes any!
);

如@cartant 所述rxjs-pipes gain types via overloads。如您所见,重载最多只应用 9 个参数(运算符)。为避免丢失类型,您可以链接多个管道:

const source$ = pipe(
  ...
  map(foo => foo),
  ...
).pipe(
  ...
  map(foo => foo),
  ...
)

this 运行 stackblitz 中检查 source$ 的类型。

简单的样本过载:

class Foo {
  add<T>(arg: T): T
  add<T, T2>(arg1: T, arg2: T2): T | T2
  add<T, T2>(arg1: T, arg2: T2, ...args: any): any
  add(...args: any) {
    return args.reduce((acc: any, curr: any) => acc + ' ' + curr, '')
  }
}

const foo = new Foo();

// type: 'first' | 'second'
const add1 = foo.add('first', 'second');
console.log(add1);

// type: any
const add2 = foo.add('first', 'second', 'third');
console.log(add2);

这个例子本身很愚蠢,但我希望它能解释为什么它在某个时候得到 any 的原因。