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

TypeScript实现带父键前缀的嵌套对象/函数扁平化及类型定义

带TypeScript类型支持的嵌套命令对象扁平化方案

需求说明

现有一个嵌套结构的TypeScript对象,内部包含函数和子对象:

const commands = {
  doSomething: () => 'Yo',
  table: {
    rows: () => 10,
    columns: () => 6,
    name: (name: string) => name + ' hello'
  },
  doSomethingElse: () => 'Boo',
  modal: {
    sub: {
      hello: () => 'hello'
    }
  }
} as const;

需要将其扁平化为键名由父键加下划线拼接的对象,同时保留完整的TypeScript类型支持,最终效果如下:

const mappedCommands = {
  doSomething: () => 'Yo',
  table_rows: () => 10,
  table_columns: () => 6,
  table_name: (name: string) => name + ' hello',
  doSomethingElse: () => 'Boo',
  modal_sub_hello: () => 'hello'
}

现有实现的createCommands函数仅能完成扁平化,但无法保留类型信息,需要改造为带类型支持的版本。


解决方案

1. 定义递归扁平化类型工具

先实现一个递归的类型工具,用来将嵌套对象的类型转换为扁平化后的类型:

// 递归扁平化命令对象的类型
type FlattenCommands<T, Prefix extends string = ''> = 
  T extends (...args: any[]) => any 
    ? { [K in Prefix extends '' ? keyof T : never]: T } // 顶层函数直接保留
    : {
        [K in keyof T as T[K] extends (...args: any[]) => any 
          ? `${Prefix}${Extract<K, string>}` 
          : `${Prefix}${Extract<K, string>}_${keyof FlattenCommands<T[K]> & string}`
        ]: T[K] extends (...args: any[]) => any 
          ? T[K] 
          : FlattenCommands<T[K]>[keyof FlattenCommands<T[K]>]
      };

2. 改造createCommands函数

调整函数的泛型定义,让返回值类型匹配扁平化后的类型,同时优化实现逻辑:

function createCommands<T, Prefix extends string = ''>(
  inputs: T,
  prepend: Prefix = '' as Prefix
): FlattenCommands<T, Prefix> {
  const mappedCommands = {} as FlattenCommands<T, Prefix>;

  Object.entries(inputs as Record<string, any>).forEach(([key, value]) => {
    if (typeof value === 'function') {
      const flatKey = `${prepend}${key}` as keyof FlattenCommands<T, Prefix>;
      mappedCommands[flatKey] = value as any;
    } else {
      const subPrefix = `${prepend}${key}_`;
      const subCommands = createCommands(value, subPrefix);
      Object.assign(mappedCommands, subCommands);
    }
  });

  return mappedCommands;
}

3. 使用示例

调用改造后的函数,即可得到带完整类型支持的扁平化对象:

// 调用函数得到扁平化对象
const mappedCommands = createCommands(commands);

// 验证类型
type Commands = typeof mappedCommands;
/*
Commands类型会被正确推导为:
{
  doSomething: () => "Yo";
  table_rows: () => 10;
  table_columns: () => 6;
  table_name: (name: string) => string;
  doSomethingElse: () => "Boo";
  modal_sub_hello: () => "hello";
}
*/

内容的提问来源于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 10:20:25