Website-Suche

javascript - TypeError: Klassenkonstruktor Client kann nicht ohne 'new' aufgerufen werden


Ich arbeite an einem Discord-Bot-Framework, das ts-node (im Skriptmodus), TypeScript und discord.js verwendet. Beim Testen der Kern-Client-Klasse erhielt ich diesen Fehler:

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)

Es gibt viele Antworten auf diese gleiche Frage auf StackOverflow, und die meisten schlagen vor, den Wert 'target' in Ihrer tsconfig auf 'es6' oder höher zu setzen. Mein Problem ist, dass die Lösung für mich nicht funktioniert.

Hier ist mein 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"]
}


Dieser Fehler tritt auf, wenn ts-node und ts-node-script verwendet werden, und ich weiß, dass es die tsconfig erkennt, da ich keine Fehler beim Verwenden von es6-Modulen erhalte.

Hoffe, dass jemand helfen kann!

Antwort #1

Da NodeJS dem CommonJS-Modulsystem folgt, denke ich, dass der Grund darin liegt, dass du module auf CommonJS setzen solltest. Und du kannst das target auf ES6 belassen, solange es nicht kaputt geht. Soweit ich weiß, unterstützen Node und moderne Browser die ES6-Syntax.

Aber was ist dann der Unterschied zwischen target und module? target ist die gesamte Syntax, auf die Sie abzielen, während module nur dafür da ist, wie Sie ein anderes Modul importieren. Und NodeJS unterstützt nur CommonJS bis Version 14.x. Daher wird empfohlen, CommonJS in einem NodeJS-Typescript-Projekt zu verwenden.


Wie ich gesagt habe, ist es einfach, wie man andere Module importieren kann. CommonJS ist ein Modulsystem, also ein System, das es dir erlaubt, andere Module zu importieren, ähnlich wie das <script>-Tag in HTML. Hier ist ein CommonJS-Beispiel.

const foobar = require('./foobar.js');
foobar();

NodeJS verwendet dieses Modulsystem, weil JavaScript noch keines hatte.

Aber dann führt EcmaScript (Javascript-Standard) ESModule ein, das eine standardisierte Alternative zu CommonJS ist. ESModule ist Teil der EcmaScript-Standardsyntax. Und seine Syntax sieht so aus.

import foobar from './foobar.js';
foobar();

Also, du benutzt ESModule, aber NodeJS versteht nur CommonJS. Deshalb müssen wir das ES6 zu CommonJS kompilieren, damit NodeJS es verstehen kann.


Aber jetzt unterstützt NodeJS ESModule auf 13.x oder 14.x (ich bin mir nicht ganz sicher). Aber NodeJS wird weiterhin CommonJS als Standard verwenden. Also musst du NodeJS sagen, dass dein Paket ESModule verwendet, wenn du es nutzen möchtest.

Es gibt mehrere Möglichkeiten, dies zu tun. Erstens, die Verwendung der .mjs-Erweiterung, und zweitens, sie standardmäßig in package.json zu ändern.

{
  "name": "my-epic-package",
  "version": "1.0.0",
  "type": "module", // here
  ...
}

Also, mit aktiviertem Typmodul können Sie die tsconfig.json behalten, um module zu verwenden.

Verwandte Artikel