Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A TypeScript version would be great, it's very hard to upgrade as-is #23

Open
hippietrail opened this issue Dec 16, 2023 · 3 comments
Open

Comments

@hippietrail
Copy link

hippietrail commented Dec 16, 2023

The new JS version of this came out just when I was looking to learn to make a Discord bot. It worked great after previous false starts in other languages.

But after getting to a certain point I tried to convert it to TypeScript and found it far beyond my capabilities. Especially the deploy-command.js

@dipamsen
Copy link
Member

Here's deploy-command.js converted to typescript:

// Slash Commands Deployment Script
// https://discordjs.guide/creating-your-bot/command-deployment.html#guild-commands/

// Importing modules using ES6 syntax
import { REST, RESTPutAPIApplicationGuildCommandsJSONBody, Routes } from "discord.js";
import { config } from "dotenv";
import fs from "node:fs";

config(); // Using dotenv config function directly

if (!process.env.TOKEN || !process.env.CLIENTID || !process.env.SERVERID) {
  throw new Error("Missing one or more required environment variables: TOKEN, CLIENTID, SERVERID");
}

type Command = RESTPutAPIApplicationGuildCommandsJSONBody[number];

const commands: Command[] = [];
const commandFiles = fs.readdirSync("./commands").filter((file) => file.endsWith(".ts"));

// Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment
for (const file of commandFiles) {
  const command = await import(`./commands/${file}`); // Using dynamic import
  if ("data" in command && "execute" in command) {
    commands.push(command.data.toJSON());
  } else {
    console.log(`[WARNING] The command ${file} is missing a required "data" or "execute" property.`);
  }
}

// Construct and prepare an instance of the REST module
const rest = new REST().setToken(process.env.TOKEN);

// and deploy your commands!
try {
  console.log(`Started refreshing ${commands.length} application (/) commands.`);

  // The put method is used to fully refresh all commands in the guild with the current set
  const data = await rest.put(Routes.applicationGuildCommands(process.env.CLIENTID, process.env.SERVERID), {
    body: commands,
  });

  if (Array.isArray(data)) {
    console.log(`Successfully reloaded ${data.length} application (/) commands.`);
  }
} catch (error) {
  // And of course, make sure you catch and log any errors!
  console.error(error);
}

@hippietrail
Copy link
Author

Thanks! Finally got around to trying this. It's working with Bun but will it work with Node? I don't have my project set up properly for tsc or npx as I haven't really learned that stuff yet and I was surprised to find Coding Train hasn't done any TypeScript videos at all or I'd follow one.

For instance, these:

const commandFiles = fs.readdirSync("./commands").filter((file) => file.endsWith(".ts"));
  const command = await import(`./commands/${file}`); // Using dynamic import

Can we import .ts files directly with Node?

@dipamsen
Copy link
Member

dipamsen commented Dec 23, 2023

@hippietrail To run typescript in node, usually it is useful to use a package to do so, eg. tsx (https://www.npmjs.com/package/tsx), which can run* typescript files in node.

To convert a node project in javascript to typescript with tsx:

  1. Install tsx and typescript packages (npm install -D tsx typescript)
  2. Convert js code to ts. (Can import ts files normally.)
  3. Run your code with npx tsx bot.ts (instead of node bot.js)

(Here, npx is "Node Package Execute", which can run node packages as command line tools. Here, npx will run the package tsx, which runs typescript code with node.)

You can check out my branch where i have converted the code to typescript to run with tsx.


*Behind the scenes, tsx will compile the typescript code to js code, and run it normally with node, but this step is hidden from the user. There are other ts runtimes as well which run node, like ts-node.

Alternatively, a node project can be setup by using tsc - the typescript compiler, to compile source ts files into js files, and then the output js files are run with node. In this case, you'd write the ts files (with imports to other ts files), and all the ts code would be compiled to js by the compiler. node would then be pointed to the output files to run them. This is possible, but usually people just use a package like tsx which does all this behind the scenes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants