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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 06:18:01