TypeScript で「can only be default-imported using the esModuleInterop flag」(TS1259) が消えない
TS1259 は esModuleInterop が無効なまま export = の CommonJS モジュールを default import すると出る。
TypeScript 5.x は esModuleInterop を true にすれば消える。
6.0 以降はこの設定が常に有効なので通常は出ず、tsconfig に esModuleInterop: false が残っていると 6.0 は TS5107、7.0 は TS5108 で止まる。
公開: 更新:
要約
Module '"express"' can only be default-imported using the 'esModuleInterop' flag(TS1259)は、export = で書かれた CommonJS モジュールを import express from 'express' の default import で読もうとしたときに出る型エラーだ。
CommonJS には ES Modules の default export が無いので、TypeScript は互換用のヘルパーを挟む esModuleInterop を有効にするよう求める。
直し方は TypeScript の版で変わる。npx tsc --version で版を確かめてから、該当する節へ進む。
- 5.x:
esModuleInteropが false だと出る。moduleがcommonjsなら未指定でも false になる。
tsconfig で true にすれば消える(「解決策(TypeScript 5.x)」)。 - 6.0 以降:
esModuleInteropは常に有効で、未指定なら出ない。
tsconfig に"esModuleInterop": falseが残っていると、6.0 は TS5107、7.0 は TS5108 で止まる(「解決策(TypeScript 6.0 以降)」)。
実行例
TypeScript 5.9.3 で esModuleInterop を無効にしたまま tsc を通すと、既定インポートの行を指して TS1259 が出て、終了コードは 2 になる。
tsconfig にフラグを足して同じコマンドを打ち直すと、エラーは消えて終了コードが 0 に変わる。
Version 5.9.3$ npx tsc
src/app.ts(1,8): error TS1259: Module '"/tmp/tmp.CNkaTQfHrj/src/legacy"' can only be default-imported using the 'esModuleInterop' flag
$ echo $?
2$ npx tsc
$ echo $?
0— 2026-09-02 時点の出力
検証環境
- 検証日
- 実行環境
node:20Debian GNU/Linux 12 (bookworm)- バージョン
- Node.js 20.20.2
- npm 10.8.2
- Python 3.11.2
- Git 2.39.5
この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。
よくある原因
export =の CommonJS モジュールを default import している:expressの型定義(@types/express)はexport = eの形で、default export を持たない。- TypeScript 5.x で esModuleInterop が false: 5.x の既定値は
moduleがnode16/nodenext/preserveのときだけ true で、commonjsなどでは未指定でも false になる(TSConfig リファレンス(新しいタブで開く))。 - TypeScript 6.0 で古い設定を黙らせている:
esModuleInteropとallowSyntheticDefaultImportsを両方 false にして"ignoreDeprecations": "6.0"を付けると、6.0 でも TS1259 が出る。
解決策(TypeScript 5.x)
1. esModuleInterop を有効化する
{
"compilerOptions": {
"esModuleInterop": true,
"module": "commonjs"
}
}これが推奨。
default import に __importDefault ヘルパーが付き、型検査も実行も通る。
有効にすると allowSyntheticDefaultImports も既定で true になる。
ただし import * as express で読んで express() と呼んでいる箇所は TS2349 に変わる(直し方は 6.0 以降の手順 3)。
2. フラグを変えられないときは import = require で読む
import express = require('express');
const app = express();module が commonjs なら、esModuleInterop が true でも false でも型検査と実行が通る。
この書き方は 6.0.3 / 7.0.2 でもそのまま通る(express 5.2.1 で確認)。import * as express は true にした時点や 6.0 へ上げた時点で TS2349 になるので、後で版を上げるならこちらのほうが手戻りが少ない。
3. allowSyntheticDefaultImports だけを true にしない
esModuleInterop が false のまま allowSyntheticDefaultImports を true にすると TS1259 は消えるが、このフラグは型検査にしか効かない。
出力にヘルパーが付かず、実行時に TypeError: (0 , express_1.default) is not a function で落ちる(5.9.3 で確認)。
解決策(TypeScript 6.0 以降)
6.0 では esModuleInterop と allowSyntheticDefaultImports を false にする指定が非推奨になり、相互運用の挙動が既定で常に有効になった(TypeScript 6.0 リリースノート(新しいタブで開く))。
7.0 は 6.0 で非推奨になった指定をすべてエラーにする(TypeScript 7.0 の告知(新しいタブで開く))。
問題になるのは tsconfig に古い設定が残っているときだ。
1. esModuleInterop: false を消す
6.0.3 では、false を書くと次のエラーで止まる。
error TS5107: Option 'esModuleInterop=false' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '"ignoreDeprecations": "6.0"' to silence this error.7.0.2 では非推奨ではなく削除扱いになり、"ignoreDeprecations": "6.0" を付けても消えない。
error TS5108: Option 'esModuleInterop=false' has been removed. Please remove it from your configuration.どちらも tsconfig から消せば直る。allowSyntheticDefaultImports: false も同じ番号のエラーになるので、一緒に消す。
2. ignoreDeprecations で黙らせない
"ignoreDeprecations": "6.0" で TS5107 を黙らせても、false の指定は 6.0 の間は効き続ける。
型検査は通るのに出力にヘルパーが付かず、実行時に TypeError: (0 , express_1.default) is not a function で落ちる。allowSyntheticDefaultImports: false も残っていれば TS1259 が出る(いずれも 6.0.3 と express 5.2.1 で確認)。
6.0 で TS1259 を見たら、まずこの 2 つの false と ignoreDeprecations を探す。
3. 関数として呼んでいる namespace import を直す
5.x で書いた import * as express from 'express' + express() は、6.0 / 7.0 では TS2349(This expression is not callable)になり、実行すると express is not a function で落ちる。
リリースノートの書き換え例どおり、import express from 'express' の default import に直す。