如何在TypeScript与RxJS中获取工厂函数回调的返回类型
解决Subject工厂函数的类型推断问题
要让subscribe能获取正确的类型,你需要给createSubject添加第二个泛型参数,用来捕获回调函数返回的Observable的具体类型。
正确的类型定义修改
将createSubject的泛型从<T>扩展为<T, U>,并把factoryFn的返回类型指定为Observable<U>:
const createSubject = <T, U>( factoryFn: ($: Observable<T>) => Observable<U> ) => { // 内部逻辑保持不变 };
这样TypeScript会自动根据你传入的factoryFn的返回值,推断出U的具体类型,login.$的类型就会被正确识别为Observable<{ username: string; id: number; password: string; }>,subscribe时的r也会自动获得正确的类型提示。
为什么之前的尝试无效
- 使用
ReturnType<typeof factoryFn>属于循环引用,TypeScript无法解析这种依赖关系 - 把
U声明在factoryFn的泛型里而非createSubject的泛型里,外层函数无法捕获这个类型 - 直接写
ReturnType不是有效的TypeScript类型,必须配合具体类型或泛型参数使用
修改后的完整代码
import './style.css'; console.clear(); import { of, map, tap, Observable, Subject } from 'rxjs'; const createSubject = <T, U>( factoryFn: ($: Observable<T>) => Observable<U> ) => { const sub = new Subject<T>(); const r = factoryFn(sub.asObservable()); function trigger(value: T) { sub.next(value); } trigger.$ = r; return trigger; }; const login = createSubject<{ username: string }>(($) => { const temp = $.pipe( tap(() => { console.log('in subject!!!'); }), map(({ username }) => ({ username, id: 1, password: 'password' })) ); return temp; }); // r会自动推断为 { username: string; id: number; password: string; } login.$.subscribe((r) => { console.log({ r }); }); login({ username: 'username' });
内容的提问来源于stack exchange,提问作者Jon Sud
相关产品推荐
相关产品推荐

