Skip to content

Latest commit

 

History

History
39 lines (26 loc) · 2.71 KB

FalseExportDefault.md

File metadata and controls

39 lines (26 loc) · 2.71 KB

❗️ Incorrect default export

The resolved types use export default where the JavaScript file appears to use module.exports =. This will cause TypeScript under the node16 module mode to think an extra .default property access is required, but that will likely fail at runtime. These types should use export = instead of export default.

Explanation

This problem occurs when a CommonJS JavaScript file appears to use an assignment pattern like module.exports = something where the corresponding type declarations say export default something. The correct syntax for the type declarations to use would be export = something. As shown in the following table, when export default something describes a CommonJS module, it describes the type of module.exports.default, not module.exports itself.

JavaScript syntax Type declaration syntax
module.exports = x export = x
exports.default = x; exports.__esModule = true export default x
export default x export default x

Consequences

Consumers using --moduleResolution node16 or nodenext will see incorrect TypeScript errors when importing the module from an ES module:

import mod from "pkg";
mod();
// ^^ This expression is not callable.
// Type 'typeof import("pkg")' has no call signatures.

This error appears even though the code is correct at runtime. The TypeScript error can be resolved by changing the code to access the .default property of the import:

import mod from "pkg";
mod.default(); // 💥

However, this likely crashes at runtime. The types misrepresent the runtime module in a way that makes it impossible to satisfy both Node and TypeScript at the same time.

This problem is typically only apparent to users under --moduleResolution node16 or nodenext in ESM files. In many bundlers, as well as in files that will be transformed to CommonJS with esModuleInterop enabled, a default import can be used to access a CommonJS module’s exports.default provided it exposes an exports.__esModule, so the inaccuracy of the typings is not easily observable. But in ES modules in Node, an imported CommonJS module’s __esModule export has no special meaning, so accessing its exports.default will always require an additional .default property access on the default import. This lack of special interop behavior in Node is only reflected in TypeScript’s node16 and nodenext modes, so users in other modes may be unaffected.

Common causes

This problem is usually caused by library authors incorrectly hand-authoring declaration files to match existing JavaScript rather than generating JavaScript and type declarations from TypeScript with tsc.