Rhys - ^Sort of related to above, does inheritance...

RRhys11/14/2022
^Sort of related to above, does inheritance work with commands?

I've got a few commands for opening menus, i.e /server-settings, /channel-settings, and originally I was going to make a base class and extend from that from those, but when trying to do that it seemed to only register the abstract class and not the inherited classes which I found odd
LLioness10011/14/2022
Can you show your code?
RRhys11/14/2022
Sorry I should have included that in the original message

I went to rewrite it to recreate the issue and it's working now šŸ˜… not sure about that one

Here's the working code

Parent:
import type { SettingsMenuView } from "@primitives/views/settings-view";
import { Command } from "@sapphire/framework";
import { findRootChannel } from "@utils/add-to-parse-data";
import type { GuildRootChannel, SettingsInteractionHandlerTypes } from "@utils/types";

export abstract class OpenSettingsMenuCommand<
  T extends SettingsInteractionHandlerTypes
> extends Command {
  // Register slash and context menu command
  public override registerApplicationCommands(registry: Command.Registry) {
    // Register slash command
    registry.registerChatInputCommand({
      name: this.name,
      description: this.description,
    });
  }

  // eslint-disable-next-line no-unused-vars
  public abstract getMenu(root_channel: GuildRootChannel): Promise<SettingsMenuView<T>>;

  public async chatInputRun(interaction: Command.ChatInputInteraction) {
    const channel_settings = await this.container.answer_overflow.channel_settings.get({
      where: {
        channel_id: interaction.channelId,
      },
    });
    if (channel_settings?.bitfield == null) {
      await interaction.reply({ content: "Channel settings not found", ephemeral: true });
      return;
    }
    const root_channel = findRootChannel(interaction);
    if (root_channel == null) {
      await interaction.reply({
        content: "Could not find a channel to update settings for",
        ephemeral: true,
      });
      return;
    }
    const menu = await this.getMenu(root_channel);
    const view = await menu.getView();
    await interaction.reply({ ...view, ephemeral: true });
  }
}


Child:
import type { ChannelSettingsWithBitfield } from "@answeroverflow/core";
import { getDefaultChannelSettings } from "@answeroverflow/core/dist/structures/channel-settings";
import { OpenSettingsMenuCommand } from "@primitives/commands/settings/open-settings-menu";
import { ChannelSettingsMenuView } from "@primitives/views/channel-settings-view";
import type { SettingsMenuView } from "@primitives/views/settings-view";
import { ApplyOptions } from "@sapphire/decorators";
import type { Command } from "@sapphire/framework";
import type { GuildRootChannel } from "@utils/types";

@ApplyOptions<Command.Options>({
  name: "channel-settings",
  description:
    "Adjust settings for the current channel. Allows you to enable indexing, mark as solution, etc.",
})
export class ChannelSettings extends OpenSettingsMenuCommand<ChannelSettingsWithBitfield> {
  public async getMenu(
    root_channel: GuildRootChannel
  ): Promise<SettingsMenuView<ChannelSettingsWithBitfield>> {
    let settings = await this.container.answer_overflow.channel_settings.get({
      where: {
        channel_id: root_channel.id,
      },
    });
    if (settings == null) {
      settings = getDefaultChannelSettings(root_channel.id);
    }
    return new ChannelSettingsMenuView(settings, root_channel);
  }
}


Trying to decide if it's overcomplicating it abstracting it this way but I'm just playing around with the setup atm to see how it feels