Reputation: 41
I'm working on a discord bot framework that uses ts-node (in script mode), typescript, and discord.js. When testing the core client class I got this error:
C:\Users\thedi\Documents\coding\JS-TS\discord-bot\src\struct\Client.ts:13
super()
^
TypeError: Class constructor Client cannot be invoked without 'new'
at new DigsClient (C:\Users\thedi\Documents\coding\JS-TS\discord-bot\src\struct\Client.ts:13:9)
at Object.<anonymous> (C:\Users\thedi\Documents\coding\JS-TS\discord-bot\test\index.ts:6:16)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Module.m._compile (C:\Users\thedi\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:1056:23)
at Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Object.require.extensions.<computed> [as .ts] (C:\Users\thedi\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:1059:12)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
at main (C:\Users\thedi\AppData\Roaming\npm\node_modules\ts-node\src\bin.ts:198:14)
There are many answers to this same question around StackOverflow, and most suggested setting the 'target' value in your tsconfig to 'es6' or higher. My problem is that the solution doesn't work for me.
Here's my code:
// src/struct/Client.ts
import { Client, ClientOptions, Snowflake } from 'discord.js';
import * as discord from 'discord.js';
interface DigsClientOptions {
ownerID?: Snowflake | Array<Snowflake>;
}
class DigsClient extends Client {
public constructor(
options?: DigsClientOptions,
discordOptions?: ClientOptions
) {
super();
this.ownerID = options.ownerID;
return this;
}
ownerID: Snowflake | Array<Snowflake>;
}
export { DigsClient, DigsClientOptions };
// test/index.ts
import { DigsClient } from '../src/index';
import { config } from 'dotenv';
config();
const token = process.env.TOKEN;
const client = new DigsClient({ ownerID: '585813838490894346' });
client.login(token);
//.tsconfig.json
{
"compilerOptions": {
"target": "es6",
"module": "es6"
},
"exclude": ["node_modules"]
}
This error occurs when using ts-node
and ts-node-script
, and I know it detects the tsconfig as I don't get errors for using es6 modules.
Hope anyone can help!
Upvotes: 3
Views: 13838
Reputation: 1182
Since NodeJS follows the CommonJS module system, I think the cause is you should set module
to CommonJS
. And you can keep the target
to ES6
as far it is not break. Because AFAIK, Node and modern Browsers support ES6
syntax.
But, then what the difference between target
and module
. target
is the whole syntax you targeting to, while module
is only just for how you import other module. And NodeJS is only supports CommonJS until version 14.x. So, it is recommended to use CommonJS
on NodeJS Typescript Project.
Like what I said, it just how you could import other module. CommonJS is a module system which is a system that allows you to import other modules, like <script>
tag on html. Here's CommonJS example.
const foobar = require('./foobar.js');
foobar();
NodeJS using this module system because Javascript didn't have one yet.
But then, EcmaScript (Javascript standard) introduces ESModule which is a standardized alternative to CommonJS. ESModule is part of EcmaScript standard syntax. And its syntax look like this.
import foobar from './foobar.js';
foobar();
So, you are using ESModule, but NodeJS is only understand CommonJS. That's why we need to compile the ES6 to CommonJS, so NodeJS can understand.
But now, NodeJS supports ESModule on 13.x or 14.x (I'm not fully sure). But NodeJS will still use CommonJS as default. So, you need to tell NodeJS that your package is using ESModule if you want to use it.
There's several option to do so. First, using .mjs
extension, and second is change it as default on package.json
.
{
"name": "my-epic-package",
"version": "1.0.0",
"type": "module", // here
...
}
So, with the type module enabled, you can keep the tsconfig.json
to use module
.
Upvotes: 2