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

TypeScript如何模拟类型层面的展开运算符实现类型复用

TypeScript类型系统模拟展开运算符实现类型复用

需求背景

需要在TypeScript类型系统中模拟JS展开运算符的行为,例如期望type tt = {...{t1:number},t2:number}等价于type tt = {t1:number,t2:number}。
具体实现目标:复用已有类型t(定义为t={t1:any; t2:any}),构造目标类型type tt = { t1:any; t2:any; specific:{t1:any; t2:any} },实现类似{ ...t; specific:t }的写法效果(实际场景中待复用的类型结构远比示例复杂)。

现有尝试的问题

  • 递归自引用写法存在缺陷:type tt = { t1:any; t2:any; specific:tt };语法可生效,但会产生非预期的无限嵌套结构:期望仅可正常访问tt.specific.t1,但该写法下tt.specific.specific甚至更深层的specific属性都会被TypeScript推断为合法,不符合需求。
  • 映射类型直接追加属性无法编译:
type t = { t1: any; t2: any;}
type tt = { [key in keyof t]: t[key], specific: tt };
//                                  ^ 映射类型语法中不允许直接追加额外属性

注:Typescript spread operator for type相关讨论不是本问题的重复问题。

实现方案

通过映射类型+交叉类型的组合即可模拟展开运算符的行为,既可以完整复用原有类型的所有属性(包括可选、只读等修饰符),也可以追加自定义属性,同时避免无限递归问题:

type t = { t1: any; t2: any; }

// 直接实现:先通过映射类型遍历取出t的所有属性,再交叉追加specific属性
type tt = { [K in keyof t]: t[K] } & { specific: t };

如果需要在多处复用这种展开逻辑,可以封装为通用工具类型:

// 通用类型展开工具,等价于类型层面的{...T, ...U}
type Spread<T, U> = { [K in keyof T]: T[K] } & U;

// 使用方式
type tt = Spread<t, { specific: t }>;

效果验证

  • 可正常访问tt.t1、tt.t2,类型与t中定义完全一致
  • 可正常访问tt.specific.t1、tt.specific.t2
  • 访问tt.specific.specific会直接抛出类型错误,不存在无限嵌套问题,完全符合预期。

内容的提问来源于stack exchange,提问作者Eliav Louski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:06:26