Unterminated regular expression literal の原因と直し方(.ts に JSX)

PR
Unterminated regular expression literal の原因と直し方(.ts に JSX)
この記事は約11分で読めます。

error TS1161: Unterminated regular expression literal.(--locale ja を付けると error TS1161: 未終了の正規表現リテラルです。)は、/ で始まる正規表現の、閉じる / が見つからないときに TypeScript が出す文です(TS1161 は、TypeScript がエラーごとに付けている番号です)。正規表現のつもりで書いていなくても、手元の出力では、.ts のファイルに JSX(<h1>Hello</h1> のようなタグの書き方)を書くと、閉じタグの / の位置で同じ文が出ます。

直し方は、正規表現の書き間違いなら、const re = /abc/; のように閉じる / を足すことです。JSX を書いたファイルなら、拡張子を .tsx に変えます。TypeScript で JSX を使うには、ファイルの名前を .tsx にすることと、tsconfig.json の jsx の設定を有効にすることの 2 つが要ります。そのファイルを拡張子を付けて import しているなら、名前を変えたあとで、その行の拡張子も直します。

どちらの原因かは、エラーの位置で見分けられます。手元の出力では、JSX のときは閉じタグ </h1> の /、正規表現の書き間違いのときは書いた正規表現の頭の / を、位置が指しました。この見分け方は、TypeScript の公式の文書には見つかっていません。手元で出した結果です。

確かめたのは、TypeScript 7.0.2 と 6.0.3(エラーの文は同じ)、Node.js 24.22.1 で、Docker の Linux で流しました(2026年10月23日)。Windows・macOS では流していません。出力に出るパスの頭は、… に省きました。

この記事でわかること
  • TS1161 の全文(英語と --locale ja)と、出る 2 つの場合(.ts に JSX を書いたとき、正規表現の / が閉じていないとき)
  • エラーの位置で 2 つを見分ける方法(手元の出力。公式の文書には無い見分け方)
  • .ts に JSX を書いたときの直し方(.tsx に変える。そのあとの jsx の設定と型)
  • ESLint・oxlint・Vite・esbuild・tsx では、どんな文で出るか

TS1161 はどんなエラー?

エラーの全文(英語と --locale ja)

.ts のファイルに JSX を書くと、TypeScript は次のように止まります(TypeScript 7.0.2。Hello.ts は 3 行のファイルです)。

export function Hello() {
  return <h1>Hello</h1>;
}
$ npx tsc --noEmit -p a-ts
a-ts/src/Hello.ts(2,20): error TS1161: Unterminated regular expression literal.
$ npx tsc --noEmit -p a-ts --locale ja
a-ts/src/Hello.ts(2,20): error TS1161: 未終了の正規表現リテラルです。

(2,20) は、2 行目の 20 桁目という意味です。日本語の文は、--locale ja を付けたときの TypeScript の文です。TypeScript 6.0.3 でも、文・行・桁は同じでした。

正規表現の書き間違いでも、同じ文が出ます。.ts に const re = /abc;(閉じる / が無い)と書いたときです。

$ npx tsc --noEmit -p r-regex
r-regex/src/regex.ts(1,12): error TS1161: Unterminated regular expression literal.
$ npx tsc --noEmit -p r-regex --locale ja
r-regex/src/regex.ts(1,12): error TS1161: 未終了の正規表現リテラルです。

正規表現リテラルとは

正規表現リテラルは、文字の並びのパターンを、2 つのスラッシュ / ではさんで書いたものです。MDN は、const re = /ab+c/; を例にしています。閉じる / が無いと、TypeScript は「正規表現がまだ終わっていない」と読みます。

どちらが原因? エラーの位置で見分ける

TS1161 の文は、JSX のときも正規表現のときも同じなので、文からは区別できません。先に、拡張子とエラーの行を見ます。ファイルの拡張子が .ts で、エラーの行に <h1> のようなタグがあれば、JSX を .ts に書いている場合です。

それでも迷うときは、エラーの位置((行,桁))を見ます。手元の出力では、位置が指す文字が、次のように違いました。

書いたもの位置指した文字
.ts に return <h1>Hello</h1>;Hello.ts(2,20)閉じタグ </h1> の /(2 行目は頭に空白が 2 つあり、 return <h1>Hello</h1>; の 20 桁目が /)
.ts に const re = /abc;regex.ts(1,12)書いた正規表現の頭の /(const re = /abc; の 12 桁目)

この表の位置は、tsc の出力です。TypeScript の Handbook・TSConfig Reference・MDN の文書には、この 2 つの見分け方を書いた文は見つかっていません。手元で試した結果として読んでください。ほかの道具では、同じファイルでも桁が違います(あとの表)。

<div className="app">Hello</div> のように属性のあるタグを .ts に書くと、TS1161 のほかに TS1005 も出ました(TypeScript 7.0.2)。

$ npx tsc --noEmit -p a2-ts
a2-ts/src/App.ts(2,15): error TS1005: '>' expected.
a2-ts/src/App.ts(2,24): error TS1005: ';' expected.
a2-ts/src/App.ts(2,37): error TS1161: Unterminated regular expression literal.

同じ書き間違いを .js のファイルにして Node.js で動かすと、2 つの場合は別の文で止まります(Node.js 24.22.1)。

$ node regex.js
…/regex.js:1
const re = /abc;
           ^

SyntaxError: Invalid regular expression: missing /
…(スタック略)

Node.js v24.22.1
$ node app.js
…/app.js:1
const el = <h1>Hello</h1>;
           ^

SyntaxError: Unexpected token '<'
…(スタック略)

Node.js v24.22.1

…(スタック略) は、エラーの発生場所を並べた行を省いたしるしです。

.ts に JSX を書いたときは? 拡張子を .tsx にする

TypeScript の Handbook は、JSX を使うために 2 つのことをするよう書いています。ファイルの名前を .tsx にすることと、jsx のオプションを有効にすることです。React の文書も、JSX を含むファイルは .tsx の拡張子にしなければならない、と書いています。.tsx は TypeScript だけの拡張子で、「このファイルには JSX が入っている」と TypeScript に伝えるものです。

手順は次のとおりです。

  1. JSX を書いたファイルの名前を、Hello.ts から Hello.tsx に変えます
  2. そのファイルを拡張子を付けて import しているなら、その行も直します。Vite の react-ts のひな形(create-vite 9.3.1)は、import App from './App.tsx' のように、拡張子を付けて import しています
  3. tsconfig.json の compilerOptions に "jsx": "react-jsx" を書きます(Vite のひな形では tsconfig.app.json に最初から入っています)。TS17004 が出るときの直し方は、Cannot use JSX unless the '--jsx' flag is provided の直し方で説明しています
  4. React の型(@types/react)が無いと TS7026 が出ます。npm install --save-dev @types/react @types/react-dom で入れます。直し方は、JSX element implicitly has type 'any' の原因と直し方にあります

手元で、同じ中身を .tsx にして "jsx": "react-jsx" を設定すると、tsc --noEmit は何も出さずに通りました(TypeScript 7.0.2・6.0.3)。

.js と .jsx と .ts と .tsx の違いの全体は、.js .jsx .ts .tsx の違いの記事で説明しています。

ESLint・oxlint・Vite・esbuild・tsx で出る文

.ts に JSX を書いたとき、TypeScript 以外の道具でも、同じ原因で止まります。同じ Hello.ts を、Vite の react-ts のひな形などで流した結果です(Node.js 24.22.1)。

道具出る文位置
tsc(TypeScript 7.0.2)error TS1161: Unterminated regular expression literal.2,20
ESLint 10.13.0(ひな形を --eslint で作ったもの)Parsing error: Unterminated regular expression literal2:19
oxlint(ひな形の npm run lint)x Unterminated regular expression2:20
Vite 8.3.5(npx vite build)[builtin:vite-transform] Unterminated regular expression2:20
esbuild 0.28.2✘ [ERROR] Unterminated regular expression2:24
tsx 4.23.15ERROR: Unterminated regular expression2:24

道具によって位置の桁が違う理由は、確かめていません。位置で見分けるときは、tsc の位置を見てください。

Vite のひな形で npm run build を流すと、vite build より先に tsc -b が止まります(ひな形の TypeScript は 6.0.3)。

$ npm run build

> vite-ox@0.0.0 build
> tsc -b && vite build

src/Hello.ts(2,20): error TS1161: Unterminated regular expression literal.

tsc -b を通さずに npx vite build だけを流すと、Vite の変換が止まりました。

$ npx vite build
vite v8.3.5 building client environment for production...
transforming...
✓ 20 modules transformed.
✗ Build failed in 762ms
error during build:
Build failed with 1 error:

[builtin:vite-transform] Unterminated regular expression
   ╭─[ src/Hello.ts:2:20 ]
   │
 2 │   return <h1>Hello</h1>;
   │                    ───┬──  
   │                       ╰──── 
───╯

Vite の詳しい使い方は、Vite の記事で説明しています。ESLint は、ESLint と Prettier の記事で説明しています。ESLint で出た文は次のとおりです(eslint 10.13.0)。

$ npm run lint

> vite-es@0.0.0 lint
> eslint .


…/vite-es/src/Hello.ts
  2:19  error  Parsing error: Unterminated regular expression literal

✖ 1 problem (1 error, 0 warnings)

(参考)esbuild に --loader:.ts=tsx を付けると、.ts を JSX として読んで、React.createElement の呼び出しに変えました。この記事の直し方は、拡張子を .tsx にすることです。

JSX を書いていないときは? 正規表現の / を確かめる

エラーの位置が、JSX のタグではなく、正規表現のつもりで書いた / を指しているときは、その正規表現の閉じる / を確かめます。const re = /abc; なら、const re = /abc/; のように、パターンを 2 つの / ではさみます。

よくある質問

JSX を書くファイルはどの拡張子にしますか?

.tsx にします。TypeScript の Handbook も、React の文書も、JSX を含むファイルは .tsx と書いています。拡張子の違いの全体は、.js .jsx .ts .tsx の違いの記事で説明しています。

JavaScript(.js)でも同じエラーが出ますか?

同じ文は出ません。Node.js 24.22.1 では、文が分かれました(上の .js の出力を見てください)。

npm run build で止まりました。Vite のエラーですか?

ひな形の npm run build は tsc -b && vite build で、先に tsc -b が TS1161 で止まったので、止めたのは Vite ではなく TypeScript です(上の出力を見てください)。

tsx で動かしても同じ文ですか?

tsx 4.23.15 は、中身が esbuild で、ERROR: Unterminated regular expression と出ました(位置は 2:24)。TypeScript の TS1161 とは、文も桁も違います。tsx の使い方と、ts-node・node との違いは、npx tsx の記事で説明しています。

まとめ

  • TS1161 は、閉じる / が見つからない正規表現があるときの文です。.ts に JSX を書くと、閉じタグの / で同じ文が出ます
  • JSX を書いたファイルは、拡張子を .tsx にします。名前を変えたら import の行も直し、jsx の設定を書きます
  • 2 つの原因は、手元の出力では、tsc の位置が指す文字で見分けられました(閉じタグの / か、正規表現の頭の / か)。公式の文書には、この見分け方は見つかっていません
  • ESLint・oxlint・Vite・esbuild・tsx でも、同じ原因で止まります。文と位置の桁は道具ごとに違います
  • この記事で確かめていないこと: 見分け方を書いた公式の文、道具によって桁がずれる理由、Vite の中の部品の名前(出力に出た builtin:vite-transform まで)、Windows・macOS

参考資料

※この記事は、2026年10月23日時点の公式の資料と照らして確かめています。誤りに気づいたらお問い合わせからお知らせください。

PR
PR
タイトルとURLをコピーしました