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

如何用函数生成TypeScript联合类型?GrammyJS Telegram Bot开发

如何用TypeScript动态生成命令名称的联合类型?

我用TypeScript和GrammyJS开发Telegram机器人,有一批频繁使用的命令,想把这些命令的名称做成联合类型在代码里用。现在我导入了命令数组,但直接map得到的是string数组,没法直接用成联合类型。请问怎么实现这个需求?相关代码如下:

import commands from "./commands.js" // 返回 Array<command>

let commandStrings = commands.map(command => command.name) // 返回 Array<string>

type SaveCommandProps = {
 executedBy:string; 
 commandName: // 我想动态生成一个联合类型 
}

function someRandomThing({executedBy:'lana', CommandName:"generated Value from import commands"}:SaveCommandProps){}

首先明确:没法用函数生成联合类型——TypeScript的类型系统是静态的,函数属于运行时逻辑,两者不互通。但我们可以通过TypeScript的静态类型工具,直接从导入的命令数组里提取出字面量联合类型,关键是要让TypeScript保留数组元素的具体字面量值,而不是把它们推断成宽泛的string类型。

具体实现步骤:

  1. 锁定命令数组的字面量类型
    如果你的commands模块导出的是常量数组,直接在导出时用as const锁定类型,让TypeScript记住每个命令名称的具体值:

    // commands.ts
    export const commands = [
      { name: 'start', description: '启动机器人' },
      { name: 'help', description: '获取帮助' },
      { name: 'settings', description: '设置' },
      // 其他命令
    ] as const;
    

    如果没法修改原模块,导入后也可以手动断言:

    import rawCommands from "./commands.js";
    const commands = rawCommands as readonly Array<{ name: string; /* 其他属性 */ }>;
    
  2. 提取命令名称的联合类型
    通过TypeScript的类型索引语法,从数组类型里提取所有name属性的字面量值,自动形成联合类型:

    type CommandName = (typeof commands)[number]['name'];
    

    这行代码的意思是:先取commands的类型,然后取数组中任意元素的类型,最后提取该元素的name属性类型,最终得到类似'start' | 'help' | 'settings'的联合类型。

  3. 在Props中使用这个联合类型
    把生成的CommandName类型直接用到你的SaveCommandProps里:

    type SaveCommandProps = {
      executedBy: string;
      commandName: CommandName;
    };
    

完整代码示例:

// commands.ts
export const commands = [
  { name: 'start', description: '启动机器人' },
  { name: 'help', description: '获取帮助' },
  { name: 'settings', description: '设置' },
] as const;

// 主文件
import { commands } from "./commands.js";

// 提取命令名称的联合类型
type CommandName = (typeof commands)[number]['name'];

type SaveCommandProps = {
  executedBy: string;
  commandName: CommandName;
};

function someRandomThing({ executedBy, commandName }: SaveCommandProps) {
  console.log(`${executedBy} 执行了命令 ${commandName}`);
}

// 合法调用(TypeScript不会报错)
someRandomThing({ executedBy: 'lana', commandName: 'start' });
// 非法调用(TypeScript会提示类型错误)
someRandomThing({ executedBy: 'lana', commandName: 'unknown' });

关键说明:

  • as const是核心:它会让TypeScript把数组和对象的所有属性都推断为字面量类型,而不是宽泛的string或object,这样才能提取出具体的联合类型值。
  • 这种方式是纯静态类型操作,完全符合TypeScript的类型系统规则,比试图用运行时函数生成类型更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 15:22:12