VSCode TypeScript rxjs map() 运算符在重复足够多后会丢失类型
Posted
技术标签:
【中文标题】VSCode TypeScript rxjs map() 运算符在重复足够多后会丢失类型【英文标题】:VSCode TypeScript rxjs map() operator loses type after enough repetitions 【发布时间】:2021-01-10 11:33:03 【问题描述】:我的问题是;是什么导致 vscode 丢失类型以及是否有任何扩展它的功能的方法。其次,任何可能的解决方法将不胜感激。
我做了一些谷歌搜索,发现了一些与无限类型递归相关的问题被放弃,但我不确定这是否属于那条船。如果是这样的话,我认为这个实例非常有趣,因为 Rxjs 是一个使用如此广泛的库,并且这个问题可以在给定管道中仅 9 次 map 调用后触发。
https://github.com/microsoft/TypeScript/issues/35533https://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!
);
【问题讨论】:
github.com/ReactiveX/rxjs/blob/… 看起来这实际上只是 Rxjs 的一个限制,这里只有 9 个可能的管道操作符,任何高于该操作符的操作符都返回到任何内容并返回 Observable。如果您想将此作为答案,我们可以将其结束。 解决方法是在 9 个运算符之后使用第二个pipe
。 test.pipe(9-operators).pipe(more-operators)
【参考方案1】:
正如@cartant 提到的rxjs-pipes 通过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
。
【讨论】:
一个伟大的发现,乔纳森!感谢您为我的问题提供答案和解决方案。我无法理解为什么我的类型在我的 map 和 mergeMap(带有他们自己的 map-calls)运算符函数的混合中会丢失。正如您所指出的:在 9 次地图调用之后,该类型漂浮到太空中,再也见不到了。以上是关于VSCode TypeScript rxjs map() 运算符在重复足够多后会丢失类型的主要内容,如果未能解决你的问题,请参考以下文章
Angular,转换 JSON,Rxjs 运算符,Typescript