TypeScript如何强制类属性为discord.js ClientEvents键并匹配execute参数类型
修改后完整代码
type Message = { // 此处为模拟的discord.js Message类型,实际使用直接导入框架内置类型即可 user: { tag: string } }; // discord.js内置的ClientEvents类型,此处仅做示例 interface ClientEvents { messageCreate: [message: Message]; // 可扩展其他事件定义 // guildCreate: [guild: Guild] } // 修正后的通用事件接口 interface EventInterface<T extends keyof ClientEvents> { name: T, // 单参数场景写法:自动匹配对应事件的第一个入参类型 execute: (interactObject: ClientEvents[T][0]) => Promise<void | undefined>; // 多参数兼容写法:适配discord.js所有事件的参数列表,更通用 // execute: (...args: ClientEvents[T]) => Promise<void | undefined>; } class MessageCreateEvent implements EventInterface<'messageCreate'> { // name如果填写非ClientEvents键值,TS会直接抛出类型错误 public name = 'messageCreate' as const; // interactObject会自动推导为对应事件的参数类型,此处为Message类型 public async execute(interactObject): Promise<void | undefined> { console.info(`Message from ${interactObject.user.tag}`); } }
核心修改说明
- 实现
name必须为ClientEvents键的约束:将EventInterface的泛型T的约束从原有错误写法改为T extends keyof ClientEvents,直接限定T只能是ClientEvents的合法键。类实现接口时如果填写不存在的事件名作为泛型参数,或者name属性值与泛型指定的事件名不匹配,TS都会直接报错拦截。 - 实现
execute入参自动匹配对应类型的约束:删除原有占位的DontKnowType,替换为ClientEvents[T][0],TS会自动根据泛型T取出对应事件的第一个参数类型绑定到execute入参。如果需要兼容discord.js中多参数的事件,直接改用剩余参数写法(...args: ClientEvents[T])即可适配所有事件的参数结构。
内容的提问来源于stack exchange,提问作者CrunchyArtie
相关产品推荐
相关产品推荐

