import
has strict syntax that lets it be statically analyzed, it cannot contain expressions.
Since debug
is CommonJS module that exports a function and not an object, it requires special treatment when being imported.
As the snippet in the question suggests, the established way to call CommonJS export in TypeScript 2.x is:
import * as debugFactory from "debug";
const debug = debugFactory("debug:namespace");
It is readable and type-safe alternative to raw require
call that doesn’t cause problems in general; ES modules may get other benefits from import
, but tree shaking is not applicable here.
Another way to write this that doesn’t contradict ES module specification and tends to be future-proof is TypeScript-specific import..require
syntax:
import debugFactory = require("debug");
const debug = debugFactory("debug:namespace");
In TypeScript 2.7 and higher, it’s possible to use esModuleInterop
compiler option that adds synthetic default
export to CommonJS modules (which debug
is) and changes import syntax to:
import debugFactory from "debug";
const debug = debugFactory("debug:namespace");
The above-mentioned ways don’t allow for one-liner that treats an import as expression and chains it with function call.
Dynamic imports can involve expressions, but since they are promise-based, this will be:
// inside async function
const debug = (await import("debug"))("debug:namespace");