discord.js机器人从JS重写为TS扩展Client后无法发消息该如何解决
解决方案
1. 给自定义Client补全类型定义
你当前自定义的DiscordClient类新增的commands、config属性属于隐式any类型,同时discord.js的Client本身需要传入泛型参数启用严格类型校验,修正后的类定义如下:
import { Client, ClientOptions, Collection } from "discord.js"; // 按你实际的配置结构定义Config类型 interface ClientConfig { ids: { channelIDs: { dev: { botTestLobby: string; }; // 补充其余用到的频道ID字段 }; // 补充其余config下的字段 }; } // 按你实际的命令结构定义Command类型 interface Command { name: string; execute: (...args: any[]) => Promise<void>; // 补充其余命令属性 } // Client<true>的泛型参数标识实例默认处于已就绪状态,自动排除缓存属性的undefined情况 export class DiscordClient extends Client<true> { // 给属性显式定义类型,消除隐式any报错 public commands: Collection<string, Command> = new Collection(); public config: ClientConfig; constructor(options: ClientOptions, config: ClientConfig) { super(options); this.config = config; } }
2. 对查询到的频道做类型收窄
channels.cache.find()返回的是多类频道的联合类型,只有文本类频道才具备send方法,需要用discord.js内置的类型谓词做类型收窄后再调用方法:
import { TextBasedChannel } from "discord.js"; const targetChannel = client.channels.cache .find(channel => channel.id === client.config.ids.channelIDs.dev.botTestLobby); // 判断频道存在且属于可发消息的文本类频道,TS会自动收窄类型 if (targetChannel?.isTextBased()) { targetChannel.send({ embeds: [loginMessage] }); }
如果你100%确定目标频道的类型,也可以用类型断言简化写法,比直接声明any更安全:
(client.channels.cache .find(channel => channel.id === client.config.ids.channelIDs.dev.botTestLobby) as TextBasedChannel) .send({ embeds: [loginMessage] });
内容的提问来源于stack exchange,提问作者Christoph Blüm
相关产品推荐
相关产品推荐

