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

如何在TypeScript中规范化嵌套类型转换结果?

问题:如何让TypeScript类型别名在编辑器中完全展开显示?

我正在开发一个类型转换类库,需要实现类型之间的转换。举个简单示例:

interface Struct {
    a: {
        x: number;
        y: number;
    };
    b: string;
}

type OmitDeepX<T> = { [K in keyof T]: Omit<T[K], 'x'> };

export type TransformedStruct1 = OmitDeepX<Struct>;

VSCode显示的类型结果逻辑正确,但作为类库用户,我期望看到完全展开的规范化类型,而非嵌套的类型别名引用:

type TransformedStruct = {
   a: {
       y: number;
   };
   b: string;
}

我在tRPC、Zod等项目中见过这种展开显示的效果,请问该如何实现?


实现方法

TypeScript默认会保留类型别名的引用关系,要让编辑器展开显示最终类型,核心是打破类型别名的封装,强制TypeScript计算并展示最终的结构。以下是几种实用方案:

1. 交叉类型强制展开

通过将类型与{}交叉,可以让TypeScript展开顶层的类型别名:

type OmitDeepX<T> = { [K in keyof T]: Omit<T[K], 'x'> } & {};

export type TransformedStruct1 = OmitDeepX<Struct>;

这种方法对顶层类型有效,但深层嵌套的类型可能仍会保留别名。

2. 通用的Prettify工具类型

定义一个通用工具类型,递归处理所有嵌套结构,确保完全展开:

type Prettify<T> = T extends infer U ? { [K in keyof U]: U[K] } : never;

// 修改你的转换类型,用Prettify包裹结果
type OmitDeepX<T> = Prettify<{ [K in keyof T]: Prettify<Omit<T[K], 'x'>> }>;

export type TransformedStruct1 = OmitDeepX<Struct>;

这个Prettify利用条件类型的推断(infer U)打破别名,再重新构造对象类型,强制TypeScript展开所有层级的结构。

3. 递归处理深层嵌套

如果需要处理更复杂的深层嵌套场景,可升级Prettify为递归版本:

type Prettify<T> = T extends object 
  ? T extends infer U 
    ? { [K in keyof U]: Prettify<U[K]> } 
    : never
  : T;

type OmitDeepX<T> = Prettify<{ 
  [K in keyof T]: T[K] extends object ? Omit<T[K], 'x'> : T[K] 
}>;

这样能确保即使是嵌套对象、数组等复杂类型,也能被完全展开显示。

原理说明

tRPC、Zod等库之所以能实现这种效果,本质是在类型转换的最终步骤中,使用类似Prettify的工具类型,强制TypeScript放弃保留类型别名引用,转而计算并展示最终的具体结构。这种处理大幅提升了类型可读性,对类库用户更友好。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 00:22:14