node.js - Klassekonstruktør kan ikke kalles uten 'new' - typescript med commonjs


Jeg lager serverside-chat med Colyseus (Node spillserver-rammeverk). Jeg bruker TypeScript med modul:commonjs fordi Colyseus er bygget på CommonJS.

Jeg har klassen ChatRoom som utvider Colyseus.Room. Ved kjøring får jeg denne feilen:

Class constructor Room cannot be invoked without 'new'.

Og problemet i JavaScript:

function ChatRoom() {
   return _super !== null && _super.apply(this, arguments) || this;
}

fra TypeScript-klasse:

import {Room} from "colyseus";

export class ChatRoom extends Room {

    onInit(options) {
        console.log("BasicRoom created!", options);
    }

    onJoin(client) {
        this.broadcast(`${ client.sessionId } joined.`);
    }

    onLeave(client) {
        this.broadcast(`${ client.sessionId } left.`);
    }

    onMessage(client, data) {
        console.log("BasicRoom received message from", client.sessionId, ":", data);
        this.broadcast(`(${ client.sessionId }) ${ data.message }`);
    }

    onDispose() {
        console.log("Dispose BasicRoom");
    }
  }

Feilen blir lett oversett når den problematiske raden fjernes etter kompilering. Men baseklassen blir ikke opprettet, og dette er ikke en komplett løsning.

Jeg googlet problemet, og det ser ut til å være relatert til babel-transpiler, selv om jeg ikke bruker babel. Jeg bruker bare tsc/tsconfig.json.

Svar #1

TypeScript transpilerer en klasse til dens ES5-motpart, men på denne måten er det nødvendig at hele klassehierarkiet transpileres til ES5.

I tilfelle foreldreklassen ikke er transpilerbar (native klasse eller importert ES6-klasse, inkludert de som ble transpilerte med Babel), vil dette ikke fungere, fordi TypeScript er avhengig av var instance=Parent.call(this, ...) || this-trikset for å kalle foreldrekonstruktøren, mens ES6-klasser kun skal kalles med new.

Dette problemet bør løses i Node.js ved å sette TypeScript target-alternativet til es6 eller høyere. Moderne Node.js-versjoner støtter ES6-klasser, det er ikke nødvendig å transpile dem.

Det samme problemet gjelder for Babel.

Svar #2

For de som bruker ts-node, kan det være mulig at din tsconfig.json ikke kan lastes av ts-node.

  1. Sørg for at du har satt følgende alternativ for tsconfig.json:
{
    "compilerOptions": {
        "target": "ES6",
        ...
    }
}
  1. Prøv ts-node --script-mode eller bruk --project for å spesifisere banen til din tsconfig.json.

Relaterte artikler