TypeScript 7.1 Betaの新機能を7.0と比べて検証|CSSやテキストのimportに型が付き、es2026が使えるように

TypeScript 7.1 Betaが10月20日に公開、7.0と並べて4つの変化を確かめた

MicrosoftのTypeScriptチームが、2026年10月20日にTypeScript 7.1 Betaを公開しました。TypeScriptは、JavaScriptに型を付けて書けるようにした言語で、Webのフロントエンドやサーバー、ツール開発で広く使われています。ベータ版は、正式版の前に新機能を試してもらうための版です。

7.1 Betaで加わった機能のうち、この記事では、CSSやテキストなど種類の違うファイルを読み込むimport文に型を付ける書き方、WebAssemblyを起動(インスタンス化)する前のモジュールとして受け取る構文、2026年版のJavaScript仕様(ES2026)向けの設定の3つを試します。このほか、他の形式のファイルをTypeScriptとして扱うcontent mappers、プログラムから型チェックを呼び出す新しいAPI、DOMの型定義の更新もあり、詳しくは公式ブログにまとまっています。一方で、条件によって型を切り替える「条件型」の一部では、7.0では通っていたコードがエラーになります。

この記事では、公式ブログの説明に沿って、最新の安定版7.0.2と7.1 Betaを同じMacに入れ、同じコードを型チェックした結果を並べます。7.1へ上げるときに書き換えが必要になる箇所と、新しい設定を実際の実行環境で使えるかも確かめました。

TypeScript 7.1 Betaの要点

新しい構文が3つ通るようになり、条件型のチェックが1つ厳しくなった

新しく通る

ファイルの種類ごとのimportの型

CSSはCSSStyleSheet、テキストはstring、バイナリはUint8Arrayとして扱える。

新しく通る

import sourceと--target es2026

7.0では構文エラーや設定エラーになったコードが、7.1 Betaでは型チェックを通る。

書き換えが必要

条件型の中の型引数の制約

7.0で通った条件型が、7.1 BetaではTS2344のエラーになる場合がある。

同じコードを型チェックした結果(2026年10月25日、macOS 27.0.1)
確かめたコードTypeScript 7.0.2TypeScript 7.1.0-beta
ファイルの種類ごとのimportの型宣言構文エラー(TS1005)通る。種類の指定がないimportはエラー
import source(WebAssembly)構文エラー(TS1005)通る
--target es2026と新しいメソッド設定エラー(TS6046)と型エラー通る
制約付きの型引数を条件型の枝で使う型通るエラー(TS2344)

CSS・テキスト・バイナリのimportに、種類ごとの型を宣言できる

JavaScriptには、import文の末尾にwith { type: "css" }のような情報を添える「import属性」という仕組みがあります。読み込むファイルがCSSなのか、ただのテキストなのかを、拡張子ではなく属性で実行環境へ伝えるためのものです。

7.1 Betaでは、型の宣言ファイル(.d.ts)の側で「この属性付きで読み込んだものは、この型になる」と宣言できるようになりました。公式ブログの例にならい、CSS、テキスト、バイナリの3種類を宣言したファイルを用意しました。

globals.d.ts

declare module "*" with { type: "css" } {
  const sheet: CSSStyleSheet;
  export default sheet;
}
declare module "*" with { type: "text" } {
  const text: string;
  export default text;
}
declare module "*" with { type: "bytes" } {
  const bytes: Uint8Array;
  export default bytes;
}

この宣言を使う側のコードには、わざと2か所の誤りを入れています。4行目は属性を付けずにCSSを読み込み、9行目はテキスト(string)を数値の変数へ入れています。

main.ts

import sheet from "./theme.css" with { type: "css" };
import notice from "./notice.txt" with { type: "text" };
import logo from "./logo.png" with { type: "bytes" };
import plain from "./theme.css";

document.adoptedStyleSheets = [sheet];
const length: number = notice.length;
const firstByte: number = logo[0];
const wrong: number = notice;
export { length, firstByte, wrong, plain };

7.0.2は、宣言ファイルのwithを読めず、構文エラー(TS1005)を9件出して止まりました。7.1 Betaは宣言を受け付け、わざと入れた2か所だけをエラーにしました。

$ npx tsc -p tsconfig.json   # TypeScript 7.1.0-beta
main.ts(4,19): error TS2307: Cannot find module './theme.css' or its corresponding type declarations.
main.ts(9,7): error TS2322: Type 'string' is not assignable to type 'number'.

1〜3行目のimportは、それぞれCSSStyleSheet、string、Uint8Arrayとして扱われ、notice.lengthやlogo[0]もエラーになりませんでした。属性を付け忘れたimportを型チェックの段階で見つけられるため、ビルドツールの設定と型の宣言がずれていないかを確かめやすくなります。

公式ブログは、この宣言はファイルが実際にあるかまでは確かめないと説明しています。また、ライブラリが公開パッケージにこの宣言を含めるのは避け、アプリを作る側が自分のプロジェクトで宣言する使い方を勧めています。

WebAssemblyを起動前のモジュールとして受け取る「import source」が通る

2つ目の新機能は、import sourceという構文への対応です。通常のimportはモジュールを読み込んで実行したあとの中身を受け取りますが、import sourceは実行前の「元のモジュール」を受け取ります。WebAssembly(ブラウザやNode.jsで動く、C言語やRustなどから作れる実行形式)なら、受け取った値をそのままWebAssembly.instantiateへ渡して、必要なときに起動できます。

import source addModule from "./add.wasm";

const instance = await WebAssembly.instantiate(addModule);
const lazy = await import.source("./add.wasm");
console.log(lazy === addModule, instance.exports);

7.0.2はこのコードの1行目を構文エラーにしました。7.1 Betaは型チェックを通し、出力したJavaScriptにもimport sourceの行がそのまま残りました。公式ブログによると、使うにはmoduleをesnext、nodenext、preserveのいずれかにし、targetかlibにesnextを含めます。

出力したJavaScriptを、2つの数を足すだけの小さなWebAssemblyファイルと一緒にNode.js 24.12.0で実行すると、trueと、関数addを含む中身が表示されました。import sourceとimport.source()で受け取った2つの値は同じもので、そこから起動もできています。

--target es2026は通るが、Node.js 24では動かないメソッドがある

3つ目は、2026年版のJavaScript仕様に合わせた設定--target es2026です。7.1 Betaでは安定した設定として使えるようになり、仕様に加わったMath.sumPrecise()(小数の誤差を抑えた合計)、Iterator.concat()、Uint8Array.fromBase64()などの型が入りました。

const total = Math.sumPrecise([0.1, 0.2, 0.3]);
const bytes = Uint8Array.fromBase64("SGVsbG8=");
const hex = bytes.toHex();
const all = Iterator.concat([1, 2].values(), [3].values()).toArray();

tsconfig.jsonで"target": "es2026"を指定すると、7.0.2は「targetに指定できるのはes2025かesnextまで」という設定エラー(TS6046)と、Math.sumPrecise、Uint8Array.fromBase64、Iterator.concatの3つが見つからないという型エラーを出しました。7.1 Betaはエラーなしで通りました。

型チェックの結果とは別に、実行環境が対応しているかも確かめました。同じ3つのメソッドを実行環境で呼び出すと、結果は次のように分かれました。

Chrome 156

ヘッドレスモードで実行

Math.sumPrecise → 0.6

Uint8Array.fromBase64 → toHex → 48656c6c6f

Iterator.concat → [1, 2, 3]

Node.js 24.12.0

同じMacで実行

Math.sumPrecise → TypeError

Uint8Array.fromBase64 → TypeError

Iterator.concat → TypeError

Chrome 156では3つとも動き(fromBase64の結果は、続けて呼んだtoHexで16進数の文字列にして確かめています)、Node.js 24.12.0では3つとも「is not a function」で止まりました。--target es2026は、出力するJavaScriptの書き方と使える型を決める設定です。サーバー側のコードで使う場合は、動かすNode.jsの版がこれらのメソッドに対応しているかを先に確かめてください。

7.1では、分配された条件型の中で型引数の制約が厳しくなる

7.1へ上げるときに書き換えが必要になりうるのが、条件型のチェックです。条件型はA extends B ? X : Yのように、型の条件で結果を切り替える書き方です。Aに1 | 2のような複数の型の組み合わせが入ると、TypeScriptは1と2に分けて別々に判定します。これを「分配」と呼びます。

7.1では、分配された枝の中のAを、元のAより狭い別の型として扱うようになりました。そのため、元のAを前提に制約を付けた型引数を枝の中で使うと、エラーになります。公式ブログの例に近いコードで確かめました。

type Show<A, B extends A> = [A, B];
type Issue<A extends number, B extends A> = A extends 0 ? never : Show<A, B>;

// TypeScript 7.1.0-beta
main.ts(2,75): error TS2344: Type 'B' does not satisfy the constraint 'A'.
  'B' is only assignable to the non-distributed 'A', but 'A' has been distributed here.

7.0.2ではエラーが出ません。エラーの説明にあるとおり、Bが収まることを保証できるのは分配される前のAで、分配された枝のAには別の確認が要るためです。公式ブログが挙げる直し方は、不要な制約を外すか、条件の確認を足すことです。枝の中でB extends A ?と確認を足すと、7.0.2と7.1 Betaの両方でエラーなしになりました。

type Issue<A extends number, B extends A> =
  A extends 0 ? never : B extends A ? Show<A, B> : never;

この書き方では、Bが分配後のAに収まらない枝がneverになります。たとえばIssue<1 | 2, 1>の結果は、[1, 1] | [2, 1]から[1, 1]に変わります。元の結果を保ちたい場合は、Show側のB extends Aという制約が本当に必要かを見直します。Showをtype Show<A, B> = [A, B];にすると、Issueを書き換えなくても、7.0.2と7.1 Betaの両方でエラーなしのまま[1, 1] | [2, 1]を保てました。

試すときはプロジェクトにbetaを入れて、型チェックだけを比べる

公式ブログは、7.0から7.1 Betaへの速度の改善も示しています。4つのスレッドで型チェックだけを行う条件で、5つの大きなオープンソースのコードの所要時間が1.2〜1.9倍速くなり、使うメモリも減りました。

7.0から7.1 Betaで型チェックが速くなった倍率(公式ブログの計測)

mui-docs 1.9倍(22.2秒 → 11.9秒)

t3code-server 1.4倍

sentry 1.3倍

bluesky 1.2倍

vscode 1.2倍(21.6秒 → 17.7秒)

--noEmit、型チェックのスレッド数は既定の4。棒の長さは倍率に比例。

ベータ版のため、本番のビルドは7.0のままにして、作業用のブランチで型チェックの結果だけを比べる手順を勧めます。

  1. 1. 作業用のブランチでbetaを入れる

    npm install -D typescript@betaで、package.jsonのTypeScriptを7.1.0-betaへ替える。

  2. 2. 型チェックだけを実行してエラーを比べる

    npx tsc --noEmitの結果を7.0の結果と並べ、TS2344など新しく出たエラーを探す。

  3. 3. es2026を使う前に実行環境を確かめる

    targetを上げる場合は、動かすブラウザやNode.jsで新しいメソッドが動くかを先に試す。

公式ブログによると、リリース候補版(RC)はベータの約1か月後に出る予定で、正式版はその少しあとです。条件型のエラーが出たコードは、RCを待たずに今の段階で直しておくと、7.0のまま使っている間もそのまま型チェックを通ります。