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 toolkit10mo 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!
slowly losing it
slowly losing itOP10mo ago
oh v14.15.2
chewie
chewie10mo ago
1. npm ls discord.js 2. pretty sure the guide has some information in regards to typescript usage
slowly losing it
slowly losing itOP10mo ago
do you know where in the guide i can find that usage?
chewie
chewie10mo ago
depends, what errors are you encountering
slowly losing it
slowly losing itOP10mo ago
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
chewie10mo 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 docs10mo ago
:class: Client @14.15.2 The main hub for interacting with the Discord API, and the starting point for any bot.
slowly losing it
slowly losing itOP10mo ago
ok thank you ❤️ should i use ts or just use js?
chewie
chewie10mo ago
ts
slowly losing it
slowly losing itOP10mo ago
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
slowly losing it
slowly losing itOP10mo ago
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 docs10mo 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.
slowly losing it
slowly losing itOP10mo ago
ah i see
chewie
chewie10mo 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
slowly losing it
slowly losing itOP10mo ago
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
felix233610mo ago
just create const commands = new Collection()
slowly losing it
slowly losing itOP10mo ago
alr thank you 👍 getting this now apologies if im bothering you btw i dont mean to
felix2336
felix233610mo ago
what are u doing xD wait lemme get on my laptop
slowly losing it
slowly losing itOP10mo ago
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
ahmood10mo ago
Why are you using client.commands if you declared commands as a variable
slowly losing it
slowly losing itOP10mo ago
🤷 im just reading the docs
slowly losing it
slowly losing itOP10mo ago
this page
discord.js Guide
Imagine a guide... that explores the many possibilities for your discord.js bot.
slowly losing it
slowly losing itOP10mo ago
when i ran everything in js, it worked perfectly fine, but after switching to ts, everything fell apart
ahmood
ahmood10mo 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
slowly losing it
slowly losing itOP10mo ago
ah ok i see now
felix2336
felix233610mo ago
using typescript is basically easy
slowly losing it
slowly losing itOP10mo ago
wdym?
felix2336
felix233610mo 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
Zerls10mo ago
why use ts if you're just going to any :Thonk:
felix2336
felix233610mo ago
this is stuff for commands
Zerls
Zerls10mo ago
so type them accordingly
felix2336
felix233610mo ago
when i export my command with data as SlashCommandBuilder and async execute as a function what type is it?
Zerls
Zerls10mo ago
you make a type
felix2336
felix233610mo ago
why should i
Zerls
Zerls10mo ago
.
felix2336
felix233610mo ago
i use any only in these variables
Zerls
Zerls10mo ago
:meguFace:
x02
x0210mo ago
any is the flextape of ts 😭
slowly losing it
slowly losing itOP10mo ago
>have an issue >dont know why >"incorrect type" >replace it with any >works perfectly
x02
x0210mo ago
if that doesnt work you do the magical
as unknown as ____
as unknown as ____
Unknown User
Unknown User10mo ago
Message Not Public
Sign In & Join Server To View
d.js docs
d.js docs10mo 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
chewie10mo ago
Or use module augmentation Which is what I personally recommend
d.js docs
d.js docs10mo 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 User10mo ago
Message Not Public
Sign In & Join Server To View
x02
x0210mo 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
felix233610mo ago
But you don't have to do it like this lmao
d.js docs
d.js docs10mo 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
x0210mo 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

Did you find this page helpful?