Litmus — 話題のニュースを、深く読み解く。 RSS
ソフトウェア

TypeScript 7.1、importのファイルを種類ごとに型で分けられる

TypeScript 7.1ベータで、importの型を属性ごとに分けられるようになり、.vueなど独自形式のファイルも外部パッケージ経由で型チェックに取り込めるようになった。

ノートパソコンの画面に表示された、importを含むプログラムコードの接写

イメージ写真 記事の内容を撮影したものではありません。Photo by Markus Winkler on Pexels

この記事には Amazon アソシエイトのリンクを含みます。

import styles from "./app.css" と書いても、styles が何の値なのかTypeScriptにはうまく伝わらない。CSSやJSONをimportするたびに、型がanyに近いものになってしまう経験がある人は多いはずだ。Microsoftは2026年10月20日、公式DevBlogでTypeScript 7.1のベータ版を発表した。importするファイルの種類ごとに型を宣言できる機能と、Vueのような独自形式のファイルを型チェックに取り込む新しい仕組みが加わっている。どちらも、これまでのTypeScriptでは難しかったことだ。

importの型を属性で決める

TypeScript 7.1では、import attributes(with { type: "..." }という書き方)に応じて型を宣言できるようになった。DevBlogの例はこうなっている。

declare module "*" with { type: "css" } {
    const content: CSSStyleSheet;
    export default content;
}

この宣言があると、type: "css" を付けてimportしたファイルは CSSStyleSheet 型として扱われる。属性の値ごとに、同じ要領で型を宣言できる。

  • type: "css" → CSSStyleSheet
  • type: "text" → string
  • type: "bytes" → Uint8Array

これまでのTypeScriptにも、declare module "*.css" のように拡張子でワイルドカード宣言をする方法はあった。ただし拡張子は目印にすぎず、実際にファイルをどう読み込むかは属性のほうが決めている。拡張子ベースの宣言では、同じ.cssでも属性次第で挙動が変わるケースを型で区別できなかった。DevBlogはこんな例を挙げている。バンドラーが既定でCSS Modulesとして読み込むファイルでも、type: "css" を付ければ生のCSSStyleSheetとして読み込むよう上書きできる。属性で型を分けられるようになったのは、この食い違いに対する答えになる。

属性を忘れるとどうなるかも、DevBlogの例に出ている。

import readme from "../README.md";
// oops, forgot an import attribute

属性なしのimportはエラーになる。宣言に一致するファイルが実際にディスク上にあるかどうかまではTypeScriptは確認せず、見つからない場合の失敗はランタイムやバンドラーのビルド時に報告される。

ここまでは、TypeScript自身が理解できるJSON・CSS・テキストのようなファイルの話だった。では、TypeScript自身が構文すら知らない形式のファイルは、どう扱われるのだろうか。

Vueなど独自形式も型チェックへ

Vueの単一ファイルコンポーネント(.vue)は、1つのファイルの中にHTML・JavaScript・CSSが混在し、HTMLの中にはさらに埋め込みのJavaScriptが入る。TypeScript自身の構文ではないので、tscがそのまま読むことはできない。この隙間を埋めてきたのが、Volarという別のプロジェクトだ。VS Codeで.vueファイルを開いたときの型チェックは、TypeScript本体ではなくVolarが担ってきた。

TypeScript 7.1では、DevBlogの表現によれば、Volarの中核にあるモデルが「第一級の機能」としてTypeScript本体に取り込まれた。これを実現する仕組みが「content mappers」になる。設定はtsconfig.jsonにこう書く。

{
  "compilerOptions": { },
  "contentMappers": [
    {
      "package": "@vue/content-mapper",
      "extensions": [".vue"],
      "options": { "target": 3.5 }
    }
  ]
}

.vueのような拡張子ごとに、変換を担うnpmパッケージを登録する形だ。TypeScriptは、対象の拡張子のファイルを読むとき、このパッケージを呼び出して型チェックできる形に変換してもらってから、中身を解析する。

ここで引っかかったのは、content mapperを有効にするには--runExternalCodeという専用フラグが要ることだ。DevBlogは、このフラグが「TypeScriptがcontent mapperを実行するために必要」だと説明し、content mapperを「実質的に任意の実行ファイル」とまで言い切っている。VS Codeで使う場合も、ワークスペースの信頼と権限の両方が必要で、js/ts.contentMappers.enabledという設定で無効化もできる。

TypeScriptの型チェッカーは、これまで自分が読める構文(JS・TS)だけを相手にする、閉じた静的解析だった。content mappersによって、知らない形式のファイルは外部のコードに変換してもらってから読む、という仕組みに変わったことになる。 フラグ名とこの言い切り方に、開発チーム自身がこれを大きな転換として意識していることが表れている。

ただし、Vue向けの@vue/content-mapperは、2026年10月20日時点ではnpmに公開されていない。DevBlogが示しているのはvuejs/language-toolsのプルリクエストにあるドラフト段階の実装で、今日この設定をそのまま書いても動かせる状態にはない。使える日が来たときに何が変わるかは分かったが、実際に試すにはもう少し待つ必要がある。

content mappersの枠組み自体は使えるようになった。では、7.1全体はいつ、どうやって試せるのだろうか。

ベータ版は今どこまで試せるか

TypeScript 7.1ベータは、次のコマンドで導入できる。

npm install -D typescript@beta

DevBlogは、今後まず速度と安定性の改善、ベータ版へのフィードバック対応を進め、約1か月後にRelease Candidateを経て正式版を出す計画だと書いている。つまり7.1はまだベータ版で、ここで紹介した仕様が正式版でそのまま確定するとは限らない。

7.1には、importの型やcontent mappers以外の変更もある。今回の「importとVueがどう型チェックに取り込まれるか」という問いからは外れるため深くは扱わないが、名前だけ挙げておく。

  • source phase imports: WebAssemblyのモジュールを評価前の状態で取り込める構文
  • typescript/sync・typescript/astなどの新しいAPIエントリポイント: コンパイラ機能をNode.js側から呼び出す窓口

気になった人は、DevBlogの該当箇所をたどってほしい。

性能面の数字も出ている。mui-docsというプロジェクトでの計測では、型チェックの実行時間が22.2秒から11.9秒(約1.9倍)に縮み、メモリ使用量も8,093 MiBから4,079 MiBへとほぼ半分になった。Microsoft自身の計測だが、7.0の時点で既に「10倍速い」とされていたところから、さらに積み増した数字になる。

まとめ

TypeScript 7.1ベータでは、importするファイルを属性ごとに型で区別できる「import attributes」が加わった。Vueのような独自形式のファイルも、外部パッケージ経由で型チェックに取り込む「content mappers」で扱えるようになった。

content mappersは、TypeScriptが初めて「自分の知らない形式のファイルを、外部のコードに変換してもらってから読む」ようになった仕組みだ。そのぶん--runExternalCodeという専用フラグと、エディタ側のワークスペース信頼が必要になる。7.1自体はベータ版で、Vue向けの実装もまだnpmに公開されていないため、両方の機能を一度に試せるのはもう少し先になる。今日npm install -D typescript@betaで確かめられるのは、import attributesによる型の書き分けのほうだ。

この記事の先を読む本を探す

特定の本を勧めるものではありません。検索結果から、いまの版と目次を確かめて選んでください。

コメント

気づきや感想をどうぞ

記事への補足や、読んで考えたことをお寄せください。個人情報や、他の人を傷つける内容の投稿はお控えください。

コメントを読み込んでいます…

    ほかの記事

    最新の記事 →