如何用函数生成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类型。
具体实现步骤:
锁定命令数组的字面量类型
如果你的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; /* 其他属性 */ }>;提取命令名称的联合类型
通过TypeScript的类型索引语法,从数组类型里提取所有name属性的字面量值,自动形成联合类型:type CommandName = (typeof commands)[number]['name'];这行代码的意思是:先取
commands的类型,然后取数组中任意元素的类型,最后提取该元素的name属性类型,最终得到类似'start' | 'help' | 'settings'的联合类型。在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
相关产品推荐
相关产品推荐

