async is a protected keyword. When you use async/await you might skip the 'async' package. If you made ES6+ properly with ECMAScript modules (ESM) you also renamed all your files *.mjs, for example index.mjs. If you have the filename index.js it is most often assumed NOT to be ESM. You have to add types / interfaces to all your ES6 code, so depending on your case it might not be feasible to make all at once, that's why I give the example in ES2015+ ESM notation.
For TypeScript you should be able to use ESM because I guess you want more up to date notation. In order to use async at top level, the async function exist for doing that. Example code for index.mjs that include ES2015+ import from ES5/CommonJS *.js with module.exports and ESM import/export and finally dynamic import:
import { createRequireFromPath } from 'module'; // ESM import
import { fileURLToPath } from 'url';
const require = createRequireFromPath(fileURLToPath(import.meta.url));
// const untypedAsync = require('async');
class Index {
  constructor() {
    this._server = null;
    this.host = `localhost`;
    this.port = 8080;
  }
  set server(value) { this._server = value; }
  get server() { return this._server; }
  async start() {
    const http = await import(`http`); // dynamic import
    this.server = http.createServer(this.handleRequest);
    this.server.on(`error`, (err) => {
        console.error(`start error:`, err);
    });
    this.server.on(`clientError`, (err, socket) => {
        console.error(`start clientError:`, err);
        if (socket.writable) {
            return socket.end(`HTTP/1.1 400 Bad Request\r\n\r\n`);
        }
        socket.destroy();
    });
    this.server.on(`connection`, (socket) => {
      const arrival = new Date().toJSON();
      const ip = socket.remoteAddress;
      const port = socket.localPort;
      console.log(`Request from IP-Address ${ip} and source port ${port} at ${arrival}`);
    });
    this.server.listen(this.port, this.host, () => {
      console.log(`http server listening at ${this.host}:${this.port}`);
    });
  }
  handleRequest(req, res) {
    console.log(`url:`, req.url);
    res.setHeader(`Content-Type`, `application/json`);
    res.writeHead(200);
    res.end(JSON.stringify({ url: req.url }));
  }
}
export default Index; // ESM export
export const randomName = new Index(); // Usage: import { randomName } from './index.mjs';
async function main() {
  const index = new Index();
  const cjs = require(`./otherfile.js`); // ES5/CommonJS import
  console.log(`otherfile:`, cjs);
  // 'async' can be used by using: cjs.untypedAsync
  await index.start();
}
main();
// in otherfile.js
const untypedAsync = require('async');
const test = {
  url: "url test",
  title: "title test",
};
module.exports = { test, untypedAsync }; // ES5/CommonJS export.
However, to use .mjs with typescript currently have some issues. Please look at the related typescript issues that are still open: .mjs input files and .mjs output files. You should at least transpile your .ts to .mjs to solve your problems. The scripts might look like (es6 to ts source):
// in package.json
"files": [ "dist" ],
"main": "dist/index",
"types": "dist/index.d.ts",
"scripts": {
    "mjs": "tsc -d && mv dist/index.js dist/index.mjs",
    "cjs": "tsc -m commonjs",
    "start": "node --no-warnings --experimental-modules ./dist/index.mjs"
    "build": "npm run mjs && npm run cjs"
},
"devDependencies": {
    "typescript": "^3.2.2"
}
// in tsconfig.json
"compilerOptions": {
    "module": "es2015",
    "target": "ES2017",
    "rootDir": "src",
    "outDir": "dist",
    "sourceMap": false,
    "strict": true
}