使用多个管道时 RXJS 类型推断如何工作打字稿
How RXJS type inference work when multiple pipe is used typescript
const of = require('rxjs').of;
const map = require('rxjs/operators').map
of(123).pipe(
map(num => num.toString()),
map(str => str.substring(0,1)),
).subscribe(console.log);
在上面的第二个map
中,str
参数的类型由前面的map
正确推断为returns一个string
。我很好奇打字稿是如何推断第二个地图运算符中的类型的。
难道是这个RxJS 把代码设计得很好才可以实现的吗?
还是只是 VS 代码对 RxJS 有特殊的 IntelliSense?
我会说这都是由 RxJS 处理的。
正在查看 pipe
overloads
pipe(): Observable<T>;
pipe<A>(op1: OperatorFunction<T, A>): Observable<A>;
pipe<A, B>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>): Observable<B>;
pipe<A, B, C>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>): Observable<C>;
...
我们可以看到发生了很多事情。
OperatorFunction<T, A>
类型是指一个函数,其单个参数是 T
类型的 Observable 并且其 return type 也是一个类型为 A
:
的 Observable
export interface OperatorFunction<T, R> extends UnaryFunction<Observable<T>, Observable<R>> {}
我们也来看看map
's signature
export function map<T, R>(project: (value: T, index: number) => R, thisArg?: any): OperatorFunction<T, R> { ... }
如您所见,它的 return 类型将是一个函数,它接收一个 observable 和 returns 另一个 observable。在这种情况下,returned Observable(R
) 的 type 是 inferred 来自提供的投影函数:(value: T, index: number) => R
所以,如果你有
const src$ = of(1).pipe(map(v => '' + v));
src$
将是一个类型 T
将是 string
的可观察对象。
这就是为什么类型推断也适用于 subscribe
:
subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription; // Providing callbacks
subscribe(observer?: PartialObserver<T>): Subscription; // Providing an observer object
其中 T
是 Observable 的推断类型(即在这种情况下来自 map
提供的 fn)。
const of = require('rxjs').of;
const map = require('rxjs/operators').map
of(123).pipe(
map(num => num.toString()),
map(str => str.substring(0,1)),
).subscribe(console.log);
在上面的第二个map
中,str
参数的类型由前面的map
正确推断为returns一个string
。我很好奇打字稿是如何推断第二个地图运算符中的类型的。
难道是这个RxJS 把代码设计得很好才可以实现的吗?
还是只是 VS 代码对 RxJS 有特殊的 IntelliSense?
我会说这都是由 RxJS 处理的。
正在查看 pipe
overloads
pipe(): Observable<T>;
pipe<A>(op1: OperatorFunction<T, A>): Observable<A>;
pipe<A, B>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>): Observable<B>;
pipe<A, B, C>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>): Observable<C>;
...
我们可以看到发生了很多事情。
OperatorFunction<T, A>
类型是指一个函数,其单个参数是 T
类型的 Observable 并且其 return type 也是一个类型为 A
:
export interface OperatorFunction<T, R> extends UnaryFunction<Observable<T>, Observable<R>> {}
我们也来看看map
's signature
export function map<T, R>(project: (value: T, index: number) => R, thisArg?: any): OperatorFunction<T, R> { ... }
如您所见,它的 return 类型将是一个函数,它接收一个 observable 和 returns 另一个 observable。在这种情况下,returned Observable(R
) 的 type 是 inferred 来自提供的投影函数:(value: T, index: number) => R
所以,如果你有
const src$ = of(1).pipe(map(v => '' + v));
src$
将是一个类型 T
将是 string
的可观察对象。
这就是为什么类型推断也适用于 subscribe
:
subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription; // Providing callbacks
subscribe(observer?: PartialObserver<T>): Subscription; // Providing an observer object
其中 T
是 Observable 的推断类型(即在这种情况下来自 map
提供的 fn)。