Migrate Node.js project to TypeScript from plain ES6

It's possible, but you'll still have to edit those files.

Either of those methods will be enough.

  1. Replace const ... = require() with import ... = require():

    import async = require('async');
    ...
    
  2. Add export {} to the top of the file:

    export {};
    const async = require('async');
    ...
    

The reason of initial issue is that in TS different files are not modules unless they explicitly declared as modules, thus they are compiled/executed in the same global scope, and that's why tsc is reporting you that async variable can't be redeclared.

From documentation:

In TypeScript, just as in ECMAScript 2015, any file containing a top-level import or export is considered a module. Conversely, a file without any top-level import or export declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).


This is the same problem as this one.

In order to be treated as ES module, a file should contain either import or export statement, otherwise a variable is considered to be declared in global scope by TypeScript compiler (even if this is not so at runtime).

The solution is same as in linked question, to add dummy export {}. This could be done in batch with regex replacement but in case CommonJS , module.exports = ... exports are already in use, there may be a conflict between them.

The use of CommonJS require() imports results in untyped code. All major libraries already have according @types/... or built-in typings. Existing NPM packages can be matched with a regex from code base in order to install relevant @types/... packages in batch, imports like const async = require('async') can be replaced in batch with import async from 'async'. This requires esModuleInterop and allowSyntheticDefaultImports options to be set.