TypeScript能否自定义泛型工具类型统一包装接口所有字段?
实现方案
你要的类型派生效果完全可以实现,根据使用场景选对应写法就行:
固定包装为BehaviorSubject的最简写法
如果只需要把接口字段包装成RxJS的BehaviorSubject,不需要兼容其他泛型包装类型,直接写个专用映射类型就行,逻辑最简单:
import type { BehaviorSubject } from 'rxjs'; type Reactive<T> = { [K in keyof T]: BehaviorSubject<T[K]> } // 直接基于Foo派生 type ReactiveFoo = Reactive<Foo>
以上写法生成的
ReactiveFoo和你手写的接口结构完全一致:value为BehaviorSubject<boolean>类型,time为BehaviorSubject<string>类型,可以直接替换使用。
通用Wrapped类型实现(支持任意单参数泛型包装器)
TypeScript 目前原生不支持高阶类型(HKT),没法直接把没填类型参数的泛型(比如不带<boolean>这类参数的BehaviorSubject)当参数传进去自动给每个字段填对应类型,但是社区有成熟的模拟方案,可以实现接近你预期的写法:
import type { BehaviorSubject } from 'rxjs'; // 高阶类型占位基础接口 interface HKT { _0: unknown } // 给包装类型填充泛型参数的工具类型 type Apply<Wrapper extends HKT, Value> = (Wrapper & { _0: Value }) extends { type: infer Instance } ? Instance : never; // 实现通用Wrapped类型 type Wrapped<Source, Wrapper extends HKT> = { [Key in keyof Source]: Apply<Wrapper, Source[Key]> } // 给BehaviorSubject做包装器注册 interface BehaviorSubjectWrapper extends HKT { type: BehaviorSubject<this['_0']> } // 最终使用 type ReactiveFoo = Wrapped<Foo, BehaviorSubjectWrapper>
这个是TS生态里通用的高阶类型模拟方案,fp-ts等函数式工具库都是用这套逻辑做类型抽象的。
踩坑提示
你示例里写的BehaviourSubject是英式拼写,RxJS官方导出的类型名是BehaviorSubject(中间没有u),拼错会直接报类型找不到的错误。
内容的提问来源于stack exchange,提问作者eXception
相关产品推荐
相关产品推荐

