Error in Discord.js Guide: The Client<boolean> type does not have a 'commands' property in Typescript

node:v16.11.0

"discord.js": "^13.2.0"

I am currently setting up a Discord bot example using Discord.js.

Following the steps outlined in this guide, I have reached the point of adding the line below:

client.commands = new Collection();

However, when I do this, Typescript throws an error:

Property 'commands' does not exist on type 'Client<boolean>'

Although I found a potential solution in this answer, I still encounter some difficulties. When attempting to extend the existing type with a

declare module "discord.js"
and defining new typings, it seems to overwrite instead of extending. Furthermore, my custom typings file doesn't recognize what a Collection is since it's specific to the updated Discord.js library. This makes me question whether such modifications should be necessary following an official guide.

If you've faced similar challenges while creating a typescript Discord bot and have discovered a more recent solution, I would greatly appreciate any insights or suggestions.

Thank you for taking the time to read this.

Answer №1

-Update-

Recently, I came across my own question while searching and realized that my initial answer was incorrect. The error we encounter when following the Discord.js guide is due to the absence of a commands property on the Client class. This discrepancy is highlighted by Typescript.

After configuring Typescript correctly for my project, adding the commands as a Collection<any, any> resolved the issue.

src/@types/discord.d.ts

import { Collection } from "discord.js";

declare module "discord.js" {
  export interface Client {
    commands: Collection<any, any>;
  }
}

tsconfig.json

{
  "compilerOptions": {
    "typeRoots": ["src/@types", "node_modules/@types"],
    "outDir": "dist"
  },
  "include": ["src"],
  "exclude": ["node_modules"],
  "extends": "@tsconfig/node18/tsconfig.json"
}

-Previous Answer-

I finally found the solution.

Create types/common/discord.d.ts

And avoid making the same mistake I did by just including this:

declare module "discord.js" {
    export interface Client {
        commands: Collection<unknown, any>
    }
}

Ensure this is at the beginning.

import { Collection } from "discord.js";

This will properly extend the existing definition and incorporate Collection without replacing it.

To make this solution work, I had to add

"@typescript-eslint/no-explicit-any": "off"
to es-lint, due to Collection extending Map and allowing any value.

Answer №2

When faced with a choice, you can either take the difficult route or opt for the simpler path. The challenging option involves:

declare module "discord.js" {
  export interface Client {
    commands: Collection<unknown, any>
  }
}

Alternatively, the easier approach is to enhance the discord class as commonly practiced by many:

// utils/Client.ts
import { Client, Collection } from "discord.js"

export default class MyClient extends Client {
  collection: Collection<any, any> // make sure to use correct type :)
  constructor(options) {
   super(options)
   this.collection = new Collection();
   this.loadCommands()
  }
  loadCommands() {
   // add your code here
  }
}

Answer №3

According to the guidelines provided in their documentation, it is recommended to extend the base Client and typecast it to include the commands property. To do this, you can create a new interface like so:

interface ClientWithCommands extends Client {
  commands: Collection<string, any>
}

Once the interface is defined, you can proceed by typecasting the Client instance using the "as" keyword:

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
  ],
}) as ClientWithCommands

Now that the typecasting is done, you can start adding your commands as shown below:

client.commands = new Collection()
...

Answer №4

While the question may have already been addressed, here's a simple solution for those who prefer not to import additional libraries:

module "discord.js" {
    export interface Client {
        foo: number;
    }
}

export {}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Modifying audio output in a React element

I am trying to incorporate background music into my React app using TypeScript. However, I am encountering an issue where changing the music in the parent component does not affect the sound playing in the child node. import React from 'react'; ...

What is the reason behind a number having its final two digits transformed into zeros?

Query Hello, I was coding my discord bot and storing user IDs in a database. I plan to use these IDs to ping or assign roles to users. Issue However, I encountered a problem where the IDs in the database are being altered. For example, from 5336929053871 ...

Can child components forward specific events to their parent component?

I created a basic component that triggers events whenever a button is clicked. InnerComponent.vue <template> <v-btn @click="emit('something-happened')">Click me</v-btn> </template> <script setup lang=" ...

What is the correct way to utilize the createAsyncThunk function in TypeScript?

You can access the entire project here. I currently have this code snippet: extraReducers: (builder) => { builder .addCase(getTodosAsync.fulfilled, (state, action:any) => { return action.payload.todos ...

The attributes of a Mongoose are represented as Document instances rather than simple values

Recently, I've observed a change in the behavior of mongoose. Every time I attempt to access the built-in string methods of my properties, I encounter an error stating undefined is not a function. I am utilizing the @nestjs/mongoose package and, upon ...

Tips for updating ion-select option to correspond with the object by utilizing the object's identifier as the value

In my code, I have a select element that looks like this. <ion-select formControlName="location" (click)="clearSectionAndTask()"> <ion-select-option *ngFor="let location of locations" value="{{location.locationId}}"> ...

Is there a way to customize the "instanceof" functionality for an ArrayBuffer?

I've been working on a project that involves using threejs to draw a filled polygon based on its vertices. Initially, I started with a square and was able to get it working perfectly on its own. However, the real issue arose when I tried to integrate ...

Exporting stylesheets in React allows developers to separate

I am trying to figure out how to create an external stylesheet using MaterialUI's 'makeStyles' and 'createStyles', similar to what can be done in React Native. I'm not sure where to start with this. export const useStyles = m ...

Access an Angular 2 component through an email hyperlink including querystring parameters

I need to create a deep link with query string parameters for a component, so that when the link is clicked, it opens up the component in the browser. For example: exmaple.com/MyComponent?Id=10 I want to include a link in an email that will open the com ...

imported classes from a module cannot be accessed within the same module

Here is some TypeScript code that I wrote: Within my module, I am importing a library called ts-events. import {SyncEvent} from 'ts-events' module MyModule{ export class MyService{ } } In the same module but in a different file, I'm ...

For every piece of information in the reply

In the past, my method of working with JSON looked like this: this.http.get('http://localhost:3000/SumOfDipVolume').subscribe(res => { for (let dipVolume of res['result']) { // some code }); However, I have now realized that ...

Having trouble locating the error in my Angular and Spring Security application

I am currently working on a project that involves integrating Spring Security with an Angular client. I have encountered an issue where, despite checking for null values in the login form on the Angular side before sending it to the Java application, the J ...

Using Typescript with Angular 2 to Implement Google Sign-In on Websites

Currently, I am in the process of creating a website that utilizes a typical RESTful web service to manage persistence and intricate business logic. To consume this service, I am using Angular 2 with components coded in TypeScript. Instead of developing m ...

Encountered "Function undefined error when invoking within a map in TypeScript"

In my function, there is a map that looks like this: mainFunc(){ // other logics data.map(function (item) { item.number = Math.round(item.number); item.total = item.last - item.first; item.quantity= item?.quantity ? quantityRange(ite ...

Obtaining the date input value from the ng2-date-picker component in Angular2

I am struggling to extract the value from a date picker input field (ng2-date-picker). Despite attempting various methods to retrieve the value, I have not been successful. For reference, here is the link to the npm package I am utilizing. This represent ...

An error occured in angular2: Cannot access the 'title' property of undefined

Here is the code snippet for my custom component: export class MoviedetailComponent implements OnInit { movie:any constructor( private getmovie: GetmovieService, private router: Router, private rout: ActivatedRoute ) { } ngOnInit() { this.r ...

An error in npm occurred: "The name "@types/handlebars" is invalid."

While attempting to install typedoc using npm, I encountered the following error: npm ERR! Invalid name: "@types/handlebars" To resolve this issue, I proceeded to install @types/handlebars directly by running: npm install @types/handlebars However, I r ...

What is the reason behind TypeScript choosing to define properties on the prototype rather than the object itself?

In TypeScript, I have a data object with a property defined like this: get name() { return this._hiddenName; } set name(value) { ...stuff... this._hiddenName = value; } However, when I look at the output code, I notice that the property is on ...

Creating a Union Type from a JavaScript Map in Typescript

I am struggling to create a union type based on the keys of a Map. Below is a simple example illustrating what I am attempting to achieve: const myMap = new Map ([ ['one', <IconOne/>], ['two', <IconTwo/>], ['three ...

Properly passing props to child components in React with TypeScript. Resolve Error ts(2322)

I am facing an issue where my code works perfectly in Javascript, but encounters problems when converted to Typescript. Despite the complexity of the question, it actually boils down to a simple query. I just wanted to share the functional JS code as a sol ...