javascriptnode.jstypescript

Enabling the use of a mixture of Typescript and JS in a Node Project


In an existing node project written in JS we're trying to enable the use of Typescript so we can use it in our ongoing refactoring.

I've added a tsConfig like so:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "sourceMap": true,
    "rootDir": "./",
    "outDir": "./tsOutput",
    "strict": true,
    "moduleResolution": "node",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["./"]
}

I've also installed the following as dev dependencies:

    "@types/express": "^4.17.14",
    "@types/node": "^18.11.9",
    "@types/node-fetch": "^2.6.2",
    "ts-node": "^10.9.1",
    "ts-node-dev": "^2.0.0",
    "typescript": "^4.9.3"

And I run tsc on build, which runs and generates a js and mapping file. I've run tried this both outputting to a separate directory and removing the outDir in the tsConfig.

To test it works, I added the following class in my test project:

class ExampleClass  {
    logSomeStuff(stringToLog : string, numberToLog : number, booleanToLog : boolean)
    {
        console.log(stringToLog);
        console.log(numberToLog);
        console.log(booleanToLog);
    }
}
export default ExampleClass;

Consume it with this JS file:

const { Example } = require("./Example.ts");

function TypescriptConsumerExample() {
  const blah = new Example();
  blah.logSomeStuff("String", 2, false);
}

module.exports = TypescriptConsumerExample;

And attempt to run this JS test:

const TypescriptConsumerExample = require("../TSExample/TSConsumerExample");

describe("TS test", () => {
  it("Should be able to call TS code", () => {
    TypescriptConsumerExample();
    console.log("Built");
  });
});

But I get this warning, which implies that it doesn't understand what TS is:

logSomeStuff(stringToLog : string, numberToLog : number, booleanToLog : boolean)
                             ^

SyntaxError: Unexpected token ':'

Equally, if I run the main project and try and call this TS class from index.js:

function TSTest()
{
    console.log("Success!");
}

export default TSTest;

I get this error:

TypeError: TSTest is not a function at Object.<anonymous> 

Solution

  • In addition to the answer provided by Dimava - adding the allowJs flag to tsconfig.json, it also turned out I missed changing this line in package.json to point to the outputs index.js file:

      "main": "./tsOutput/index.js",
    

    In combination with the following:

     "scripts": {
        "start": "tsc && node  --unhandled-rejections=warn ./tsOutput/index.js",
        "dev": "tsc && node --unhandled-rejections=warn ./tsOutput/index.js",