Im new to Typescript and writing a Discord bot using Typescript. I want to add a variable "commands" to the Client object. For example in Javascript, you using this:
Javascript
const { Client } = require('discord.js');
const client = new Client();
client.commands = 'commands';
console.log(client.commands);
// 'commands'
but now I want to add something similar to Typescript. But when Im using this in Typescript, I got the following error:
Property 'commands' does not exist on type 'Client'.ts(2339)
How can I solve this?
My code at the moment:
export class HalloClient {
private client: Client;
constructor() {
this.client = new Client();
this.client.commands = new Collection();
}
public start(): void {
console.log(`- Client | Starting process...`);
new RegisterEvents('../events/', this.client).load();
new MongoConnection(process.env.mongouri).createConnection();
console.log(this.client);
this.client.login(process.env.token);
}
}
I was having the same issue when using typescript and following the guide from https://discordjs.guide
By default, commands
is not an existing attribute type on Discord.Client
object, but you can easily extend Discord.js typings with your own type by creating a .d.ts
file.
I have discord.d.ts
file on my project directory, and it contains:
declare module "discord.js" {
export interface Client {
commands: Collection<unknown, any>
}
}
This fixes my issue.
Or even better if you are using the single-file style command from discord.js guide:
import { Message } from "discord.js";
declare module "discord.js" {
export interface Client {
commands: Collection<unknown, Command>
}
export interface Command {
name: string,
description: string,
execute: (message: Message, args: string[]) => SomeType // Can be `Promise<SomeType>` if using async
}
}
This way, you also get code completion when accessing a command object from this.client.commands.get("commandName")
, and you also can import Command
type if you need it from import { Command } from "discord.js"
.
I find this useful when I want to strictly type my exported command from my command file, for example:
import { Command } from "discord.js";
// Now `command` is strictly typed to `Command` interface
const command: Command = {
name: "someCommand",
description: "Some Command",
execute(message, args): SomeType /* Can be Promise<SomeType> if using async */ {
// do something
}
};
export = command;