Of these three ways of importing a CommonJS module from TypeScript:
import * as foo from "foo
import foo = require("foo")
const foo = require("foo")
Which is most forwards-compatible with both TS and the ES module spec?
That is, when/if the "foo" library switches to using ES modules, which of the above is least likely to break or or become weird?
update: (1) looks best since it's real ES Module syntax, but I am concerned about preserving the intended semantics of the CommonJS module we're importing. For example, if a side effect is expected to run when the module is imported, we'd want to preserve that semantics when using import * as
syntax.
Another update: We're targeting ES modules. A separate tool does the ES Module -> transformation.
const foo = require("foo")
This one is the worst one, foo
will be typed as any, I would avoid it at all cost
import foo = require("foo")
This is typescript specific import syntax, and again should be avoided as much as possible. At runtime it is compiled to var foo = require("foo")
, but at compile time it offers type safety. It is the only way to import a module that uses export assignment.
import * as foo from "foo"
This is the official ES2015 syntax and should be favored whenever possible (except for the export assignment case I think it can be used in all other cases).
If you compile to commonjs
the above syntax will still be transpiled as const foo = require("./foo");
at runtime so it should behave in the same way.
There is one caveat to this, typescript will not emit imports that are unused and import that are only used for their types (read here) so if you want to import a module for side effects you can use this syntax:
import "foo"