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

TypeScript嵌套泛型Command类型:如何实现子命令context正确推断?

解决TypeScript自嵌套泛型命令的类型推断问题

你的问题出在CommandSubs的定义上——它强制所有子命令的参数类型为固定的CommandArgs,而非每个子命令自己的具体参数结构,导致TypeScript无法推断子命令main函数的context类型。以下是修复方案:

问题根源

原代码中CommandSubs = Record<string, Command<CommandArgs, CommandSubs>>的定义,把所有子命令的Args泛型固定成了CommandArgs(即任意string到CommandArg的映射),丢失了每个子命令args的具体结构信息,所以子命令的main函数只能推断出context是宽泛的CommandArgs,而非你定义的{newTest: CommandArg}。

修复后的代码

export interface CommandArg {
  type?: 'boolean' | 'number' | 'positional' | 'string'
  alias?: string
}

export type CommandArgs = Record<string, CommandArg>

// 移除原固定泛型的CommandSubs,改为让子命令的类型自动推断
export interface Command<Args extends CommandArgs = CommandArgs, Subs extends Record<string, Command> = Record<string, Command>> {
  args?: Args
  subs?: Subs
  main?: (context: Args) => unknown
}

export function defineCommand<Args extends CommandArgs, Subs extends Record<string, Command>>(command: Command<Args, Subs>) {
  return command
}

const cmd = defineCommand({
  args: {
    test: {
      type: 'boolean',
      alias: 'haha'
    }
  },
  subs: {
    haha: {
      args: {
        newTest: {
          type: 'boolean',
          alias: 'haha'
        }
      },
      main: (context) => {
        console.error(context.okok) // 此处会报错:类型“{ newTest: CommandArg; }”上不存在属性“okok”
        console.error(context.newTest.type) // 正常推断,无报错
      }
    }
  },
  main: (context) => {
    console.error(context.test.type) // 正常推断,无报错
  }
})

关键修改点

  1. 移除固定泛型的CommandSubs:原类型限制了子命令的参数类型,改为让Command的Subs泛型接受任意Record<string, Command>,保留每个子命令的具体类型信息。
  2. 简化Command接口的subs定义:去掉原代码中多余的类型映射(Subs & { [K in keyof Subs]: ... }),因为Subs本身已经是Command类型的集合,无需额外约束。
  3. 调整泛型默认值:给Command的泛型参数加上默认值,避免使用时手动指定。

进一步优化(支持深度嵌套子命令)

如果需要支持多层嵌套的子命令,TypeScript的递归泛型可以自动处理,上述代码已经具备这个能力。例如添加更深层级的子命令,其main函数的context依然能正确推断:

const cmd = defineCommand({
  args: { test: { type: 'boolean' } },
  subs: {
    haha: {
      args: { newTest: { type: 'boolean' } },
      subs: {
        deeper: {
          args: { deepArg: { type: 'string' } },
          main: (context) => {
            console.error(context.deepArg.type) // 正确推断
          }
        }
      },
      main: (context) => console.error(context.newTest)
    }
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:12:17