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

调用interaction.options.getSubcommand()遇TS类型错误,如何解决?

Discord.js TypeScript调用getSubcommand()报错的解决方法

错误信息

Property 'getSubcommand' does not exist on type 'Omit<CommandInteractionOptionResolver, "getMessage" | "getFocused" | "getMentionable" | "getRole" | "getAttachment" | ... 6 more ... | "getSubcommand">'.

你的代码

Hello.ts

import {
  CommandInteraction,
  CommandInteractionOptionResolver,
  SlashCommandBuilder,
} from "discord.js";
import { CustomClient } from "../Client";
import { Command } from "../Command";

export default class HelloCommand extends Command {
  public constructor(client: CustomClient) {
    super(client, {
      name: "hello",
      description: "Says hello to user.",
    });
  }

  public getOptions() {
    return new SlashCommandBuilder()
      .setName(this.name)
      .setDescription(this.description)
      .addSubcommand((subcommand) =>
        subcommand.setName("say").setDescription("Say hello to someone.")
      ) as SlashCommandBuilder;
  }

  public async execute(interaction: CommandInteraction): Promise<void> {
    const subcommand = interaction.options.getSubcommand();
    if (subcommand === "say") {
      interaction.reply({ content: `Hello, ${interaction.user.username}` });
    }
  }
}

Command.ts

import { CommandInteraction, PermissionResolvable } from "discord.js";
import { CustomClient } from "./Client";
import { SlashCommandBuilder } from "@discordjs/builders";

interface CommandOptions {
  name: string;
  description: string;
  permission?: PermissionResolvable;
}

export abstract class Command {
  public client: CustomClient;
  public name: string;
  public description: string;
  public permission?: PermissionResolvable;

  constructor(client: CustomClient, props: CommandOptions) {
    this.client = client;
    this.name = props.name;
    this.description = props.description;
    this.permission = props.permission;
  }

  abstract getOptions(): SlashCommandBuilder;

  abstract execute(interaction: CommandInteraction): any;
}

问题原因

你在Command.ts中使用了宽泛的CommandInteraction类型作为execute方法的参数,但这个类型包含了上下文菜单命令(ContextMenuCommandInteraction)这类没有子命令的交互类型。TypeScript无法确定传入的交互一定是带有子命令的斜杠命令,因此会将getSubcommand()这类仅斜杠命令支持的方法从类型中排除,导致报错。

解决方法

将Command.ts和Hello.ts中的交互类型替换为**ChatInputCommandInteraction**——这是专门用于斜杠命令的交互类型,TypeScript会默认其支持子命令相关方法。

修改后的Command.ts

import { ChatInputCommandInteraction, PermissionResolvable } from "discord.js";
import { CustomClient } from "./Client";
import { SlashCommandBuilder } from "@discordjs/builders";

interface CommandOptions {
  name: string;
  description: string;
  permission?: PermissionResolvable;
}

export abstract class Command {
  public client: CustomClient;
  public name: string;
  public description: string;
  public permission?: PermissionResolvable;

  constructor(client: CustomClient, props: CommandOptions) {
    this.client = client;
    this.name = props.name;
    this.description = props.description;
    this.permission = props.permission;
  }

  abstract getOptions(): SlashCommandBuilder;

  abstract execute(interaction: ChatInputCommandInteraction): any;
}

修改后的Hello.ts

import {
  ChatInputCommandInteraction,
  SlashCommandBuilder,
} from "discord.js";
import { CustomClient } from "../Client";
import { Command } from "../Command";

export default class HelloCommand extends Command {
  public constructor(client: CustomClient) {
    super(client, {
      name: "hello",
      description: "Says hello to user.",
    });
  }

  public getOptions() {
    return new SlashCommandBuilder()
      .setName(this.name)
      .setDescription(this.description)
      .addSubcommand((subcommand) =>
        subcommand.setName("say").setDescription("Say hello to someone.")
      ) as SlashCommandBuilder;
  }

  public async execute(interaction: ChatInputCommandInteraction): Promise<void> {
    const subcommand = interaction.options.getSubcommand();
    if (subcommand === "say") {
      interaction.reply({ content: `Hello, ${interaction.user.username}` });
    }
  }
}

这样修改后,TypeScript就能正确识别interaction.options包含getSubcommand()方法,报错会消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 11:44:54