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

如何将嵌套对象的函数键扁平化为单层TypeScript类型?

实现TypeScript嵌套对象的函数类型单层扁平化

问题场景

现有如下嵌套结构的对象:

const items = {
  get: (name: string) => '-' + name,
  log: () => { console.log('Hello') },
  commands: {
    table: (name: string) => 'table-' + name,
    // 可扩展更多函数/嵌套对象
  }
  // 可扩展更多函数/嵌套对象
}

需要将其类型扁平化为单层结构,只保留所有函数的键名和对应类型,最终目标类型如下:

interface Items {
  get: (name: string) => string;
  log: () => void;
  table: (name: string) => string;
}

你当前尝试的递归映射类型无法实现扁平化:

type Mapped<T extends Record<string, any>> = {
  [K in keyof T]: T[K] extends Record<string, unknown> ? Mapped<T[K]> : T[K];
};

type Items = Mapped<typeof items>;

上述代码只会递归嵌套类型,不会将深层的键提升到顶层。

解决方案

可以通过递归提取所有函数键值对,再合并为单层类型的方式实现:

// 提取对象中所有非嵌套对象的键值对(即函数类型)
type ExtractFunctions<T> = {
  [K in keyof T]: T[K] extends Record<string, unknown> ? never : T[K];
} extends infer U ? { [K in keyof U as U[K] extends never ? never : K]: U[K] } : never;

// 递归提取所有层级的函数类型,再合并
type FlattenFunctions<T> = 
  ExtractFunctions<T> & 
  (T extends Record<string, infer V> ? FlattenFunctions<V> : never);

// 最终生成单层扁平化类型
type Items = FlattenFunctions<typeof items>;

代码解释

  1. ExtractFunctions<T>:遍历当前层级的键,过滤掉值为嵌套对象的键,只保留函数类型的键值对。通过never标记不需要的键,再重新构造过滤后的类型。
  2. FlattenFunctions<T>:先提取当前层级的函数类型,再递归处理当前层级中所有嵌套对象的函数类型,最后通过交叉类型(&)合并所有层级的键值对。TypeScript会自动将交叉类型合并为单层接口结构。

测试验证:Items类型最终会和目标接口完全一致,所有深层函数都会被提升到顶层。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:25:22