Run factory function on import in TypeScript?

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");

Leave a Comment