You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 23:42:19