hopefully two simple questions

1. how do I check my djs version? i just installed it and idk how to check 2. how can i use djs with typescript? i keep getting type errors cuz idk what to annotate stuff with im also very new, its awesome to be here 🙏
52 Replies
d.js toolkit
d.js toolkit7mo ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button!
it’s raining outside
oh v14.15.2
chewie
chewie7mo ago
1. npm ls discord.js 2. pretty sure the guide has some information in regards to typescript usage
it’s raining outside
do you know where in the guide i can find that usage?
chewie
chewie7mo ago
depends, what errors are you encountering
it’s raining outside
just missing type annotations the same that you would get if you did this
function add (a, b) {
return a + b;
};
function add (a, b) {
return a + b;
};
can't compile TypeScript: a has an implicit any annotation etc
chewie
chewie7mo ago
Yeah, you gonna have to add the required annotations yourself, thats part of typescript you can find all types in the documentation though
d.js docs
d.js docs7mo ago
:class: Client @14.15.2 The main hub for interacting with the Discord API, and the starting point for any bot.
it’s raining outside
ok thank you ❤️ should i use ts or just use js?
chewie
chewie7mo ago
ts
it’s raining outside
ok
file:///c:/Users/user/OneDrive/Desktop/i%20hate%20programming/javascript%20(pain)/index.js:1
const fs = require('node:fs');
^

ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and 'c:\Users\user\OneDrive\Desktop\i hate programming\javascript (pain)\package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
at file:///c:/Users/user/OneDrive/Desktop/i%20hate%20programming/javascript%20(pain)/index.js:1:12
at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
at async loadESM (node:internal/process/esm_loader:34:7)
at async handleMainPromise (node:internal/modules/run_main:113:12)

Node.js v20.10.0
file:///c:/Users/user/OneDrive/Desktop/i%20hate%20programming/javascript%20(pain)/index.js:1
const fs = require('node:fs');
^

ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and 'c:\Users\user\OneDrive\Desktop\i hate programming\javascript (pain)\package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
at file:///c:/Users/user/OneDrive/Desktop/i%20hate%20programming/javascript%20(pain)/index.js:1:12
at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
at async loadESM (node:internal/process/esm_loader:34:7)
at async handleMainPromise (node:internal/modules/run_main:113:12)

Node.js v20.10.0
it’s raining outside
so just change the file extension? this shit is confusing i changed it to .cjs then it told me to change it to .mjs then fs cant be imported from node:fs
import { fs } from 'node:fs';
^^
SyntaxError: The requested module 'node:fs' does not provide an export named 'fs'
at ModuleJob._instantiate (node:internal/modules/esm/module_job:132:21)
at async ModuleJob.run (node:internal/modules/esm/module_job:214:5)
at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
at async loadESM (node:internal/process/esm_loader:34:7)
at async handleMainPromise (node:internal/modules/run_main:113:12)

Node.js v20.10.0
import { fs } from 'node:fs';
^^
SyntaxError: The requested module 'node:fs' does not provide an export named 'fs'
at ModuleJob._instantiate (node:internal/modules/esm/module_job:132:21)
at async ModuleJob.run (node:internal/modules/esm/module_job:214:5)
at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
at async loadESM (node:internal/process/esm_loader:34:7)
at async handleMainPromise (node:internal/modules/run_main:113:12)

Node.js v20.10.0
2 things: 1. what do i do then? im going off the docs as a basic guide 2. what does "destructure" mean in javascript terms?
d.js docs
d.js docs7mo ago
:mdn: Destructuring assignment The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
it’s raining outside
ah i see
chewie
chewie7mo ago
what do i do then? im going off the docs as a basic guide
Either import everything from the module and name that variable fs, as usual, or just import the individual functions
it’s raining outside
hm ok i see confused why this wont let me assign the collection instance to the commands attribute like it says in the docs 🤷
felix2336
felix23367mo ago
just create const commands = new Collection()
it’s raining outside
alr thank you 👍 getting this now apologies if im bothering you btw i dont mean to
felix2336
felix23367mo ago
what are u doing xD wait lemme get on my laptop
it’s raining outside
import * as fs from 'fs';
import * as path from 'path';

import { readFileSync } from "fs";
import { Client, Collection, Events, GatewayIntentBits } from 'discord.js';
const token = readFileSync('./token.txt', 'utf-8');

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

const commands = new Collection();

const foldersPath = path.join(__dirname, 'commands');
const commandFolders = fs.readdirSync(foldersPath);

for (const folder of commandFolders) {
const commandsPath = path.join(foldersPath, folder);
const commandFiles = fs.readdirSync(commands.Path).filter(file => file.endsWith('.js'));

for (const file of commandFiles) {
const filePath = path.join(commandsPath, file);
const command = require(filePath);

if ('data' in command && 'execute' in command) {
client.commands.set(command.data.name, command);
} else {
console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
}
}
}

client.once(Events.ClientReady, readyClient => {
console.log(`Ready! Logged in as ${readyClient.user.tag}`)
})

client.login(token);
import * as fs from 'fs';
import * as path from 'path';

import { readFileSync } from "fs";
import { Client, Collection, Events, GatewayIntentBits } from 'discord.js';
const token = readFileSync('./token.txt', 'utf-8');

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

const commands = new Collection();

const foldersPath = path.join(__dirname, 'commands');
const commandFolders = fs.readdirSync(foldersPath);

for (const folder of commandFolders) {
const commandsPath = path.join(foldersPath, folder);
const commandFiles = fs.readdirSync(commands.Path).filter(file => file.endsWith('.js'));

for (const file of commandFiles) {
const filePath = path.join(commandsPath, file);
const command = require(filePath);

if ('data' in command && 'execute' in command) {
client.commands.set(command.data.name, command);
} else {
console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
}
}
}

client.once(Events.ClientReady, readyClient => {
console.log(`Ready! Logged in as ${readyClient.user.tag}`)
})

client.login(token);
tihis is my whole code
ahmood
ahmood7mo ago
Why are you using client.commands if you declared commands as a variable
it’s raining outside
🤷 im just reading the docs
it’s raining outside
this page
discord.js Guide
Imagine a guide... that explores the many possibilities for your discord.js bot.
it’s raining outside
when i ran everything in js, it worked perfectly fine, but after switching to ts, everything fell apart
ahmood
ahmood7mo ago
Then keep using js, you have to understand how typescript works first if you're gonna switch The whole point of typescript is it's type system, the reason you cannot use client.commands is because Client doesn't have a commands property, you have to declare it or extend the class
it’s raining outside
ah ok i see now
felix2336
felix23367mo ago
using typescript is basically easy
it’s raining outside
wdym?
felix2336
felix23367mo ago
wait
const cw = new ConsoleWarning()
const ci = new ConsoleInfo()
const commands = new Collection<string, any>()
const apps: any[] = []
const subDirs = readdirSync('./Commands')
for (const dir of subDirs) {
const files = readdirSync(`./Commands/${dir}`)
for (const file of files) {
const module = await import(`./Commands/${dir}/${file}`)
const command = module.default
if (!command || !command.data || !command.data.name || !command.data.description) {
cw.show(`Befehl in Commands/${dir}/${file} ist ungültig`)
continue
}

commands.set(command.data.name, command)
apps.push(command)
ci.show(`Befehl "/${command.data.name}" geladen`)
}
}
const cw = new ConsoleWarning()
const ci = new ConsoleInfo()
const commands = new Collection<string, any>()
const apps: any[] = []
const subDirs = readdirSync('./Commands')
for (const dir of subDirs) {
const files = readdirSync(`./Commands/${dir}`)
for (const file of files) {
const module = await import(`./Commands/${dir}/${file}`)
const command = module.default
if (!command || !command.data || !command.data.name || !command.data.description) {
cw.show(`Befehl in Commands/${dir}/${file} ist ungültig`)
continue
}

commands.set(command.data.name, command)
apps.push(command)
ci.show(`Befehl "/${command.data.name}" geladen`)
}
}
This is my command handler the only thing different to js is this
Zerls
Zerls7mo ago
why use ts if you're just going to any :Thonk:
felix2336
felix23367mo ago
this is stuff for commands
Zerls
Zerls7mo ago
so type them accordingly
felix2336
felix23367mo ago
when i export my command with data as SlashCommandBuilder and async execute as a function what type is it?
Zerls
Zerls7mo ago
you make a type
felix2336
felix23367mo ago
why should i
Zerls
Zerls7mo ago
.
felix2336
felix23367mo ago
i use any only in these variables
Zerls
Zerls7mo ago
:meguFace:
x02
x027mo ago
any is the flextape of ts 😭
it’s raining outside
>have an issue >dont know why >"incorrect type" >replace it with any >works perfectly
x02
x027mo ago
if that doesnt work you do the magical
as unknown as ____
as unknown as ____
Unknown User
Unknown User7mo ago
Message Not Public
Sign In & Join Server To View
d.js docs
d.js docs7mo ago
:mdn: extends The extends keyword is used in class declarations or class expressions to create a class that is a child of another class.
chewie
chewie7mo ago
Or use module augmentation Which is what I personally recommend
d.js docs
d.js docs7mo ago
We highly recommend you extend the Client structure properly instead of just attaching custom properties like .commands to the regular discord.js Client instance. - Using typescript, you might want to consider casting or augmenting the module type
Unknown User
Unknown User7mo ago
Message Not Public
Sign In & Join Server To View
x02
x027mo ago
i would beg to differ, “as unknown as” is on the same level as “any”, as with either one you should be switching back to js only difference is the “as unknown as” is a suggestion 🤷‍♂️ oh trust me i know, theyre the exception only because i dont wanna lose access to vscode 😭 and possibly keep my life yes im hypocritical because i also use “as unknown as” no i should suggestedly switch back to js, thats my logic
channel.send({ embeds: [embed], components: [row as unknown as APIActionRowComponent<APIMessageActionRowComponent>] })
channel.send({ embeds: [embed], components: [row as unknown as APIActionRowComponent<APIMessageActionRowComponent>] })
an action row builder :ch_hehe:
felix2336
felix23367mo ago
But you don't have to do it like this lmao
d.js docs
d.js docs7mo ago
In TypeScript the ActionRowBuilder class has a generic type parameter that specifies the type of component the action row holds:
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(button)
const row = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(selectMenu)
const row = new ActionRowBuilder<TextInputBuilder>().addComponents(textInput)
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(button)
const row = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(selectMenu)
const row = new ActionRowBuilder<TextInputBuilder>().addComponents(textInput)
x02
x027mo ago
see but i learned that the more lines the better your code is so this is against my morals gosh you might be right hmmm shouldve made a new variable to declare it as unknown as instead smh myself but there i cant make custom typings, or use cool commented out typings at all!!
interface Replace {
[key: string]: string | ((word: string) => string);
}
interface Replace {
[key: string]: string | ((word: string) => string);
}
but then my files would look like normie orange :ch_nananono: so much extra work… though this is the guide i follow the only true guide btw all the other ones spread lies
Want results from more Discord servers?
Add your server