2026-03 の TC39 meeting
まとめ
Agenda: https://github.com/tc39/agendas/blob/main/2026/03.md
速報: https://x.com/robpalmer2/status/2032198919807959270
Note: https://github.com/tc39/notes/tree/main/meetings/2026-03
決まったこと
Web compatibility issues / Needs Consensus PRs
N/A
Stage 4 (ES2026)
Temporal for Stage 4 (slides, ECMA-262 PR, ECMA-402 PR) | Philip Chimento
https://gyazo.com/acc656233cd291e66836ef1e627c8ffc
SpiderMonkey と V8 にシップ、非モダンブラウザのエンジンでは Ladybird と Kiesel と Boa にシップ。
Web Platform Integrations を進めている。structuredClone や <input type="date"> など。
https://github.com/tc39/proposal-temporal/issues/3075
Stage 4 になった 🎉
https://gyazo.com/9431f4f10caf047825312d7936ab2084
https://gyazo.com/251633a9fa146af8084d0c98b197211b
今後 Temporal V2 として後回しされた提案仕様を進めていくことになる。
https://github.com/js-temporal/proposal-temporal-v2
Intl Era/Month Code for Stage 4 (slides, PR) | Ben Allen
Temporal 同様こちらも Stage 4 になった 🎉
Stage 3
import defer interaction with tc39/ecma262#3715, and normative PR Shield dynamic import defer against Promise.prototype monkey patch (PR#77, PR#79, slides) | Nicolò Ribaudo
2025-11 の TC39 meeting でネームスペースオブジェクトを re-export する際に、他の仕様と異なり 2 step に分かれていた Normativa Change が承認され、仕様に既に入っている。これにより import defer も修正する必要があったのが承認された(PR#79)。
import.defer() で PerformPromiseAll を使っているが、これは Promise.prototype.then 汚染に耐性がない問題があった。そこで新たに SafePerformPromiseAll という PerformPromiseThen を直接呼び出すオペレーターを追加し、そちらを呼ぶ Normative Change が承認された(PR#77)。
Explicit Resource Management Conditional Stage 4 Status Update (spec PR, test262 PRs, slides) | Ron Buckton
Stage 4 目前だが、test262 や ECMA-262 への PR のレビューがボトルネックになっている。
Import Text for Stage 2.7 or 3 (slides, PR #10) | Eemeli Aro
仕様側で特に制限が追加されたわけではないが、textual data を読み込むものとして扱う Normative Change が入った。
Web 標準側で MIME を見てテキストでなければ例外を出すような仕様になりそうかと思ったが何を持ってテキストとするのかが明確ではない(例えば2024年以降に追加された application/yaml はどうするのかとか)ので特にバリデーションはされなそう。
https://github.com/whatwg/html/pull/11933#issuecomment-4133866999
Stage 3 になった。
Stage 2.7
Intl: Keep Trailing Zeros for Stage 3 (slides) | Eemeli Aro
Intl.NumberFormat で末尾の 0 を残したい提案。
とても小さい数値を渡したときに末尾の 0 の数を合わせるかどうか(PR#15)について議論され、変更する方向になった。
code: js
let nf = new Intl.NumberFormat('en', { maximumFractionDigits: 5 });
// before
nf.format('1.2e-10') // '0.0'
// after
nf.format('1.2e-10') // '0.00000'
整数の末尾の 0 は有効数字として扱うか(PR#17)については結論が出なかった。
code: js
let nf = new Intl.NumberFormat('en', { notation: 'scientific' });
// before
nf.format('700') // '7.00E2'
// after
nf.format('700') // '7E2'
今回は Stage 3 に進まず。
Update on ESM Phase Imports (slides, PRs #56, #58 (normative) & #61 (normative)) | Guy Bedford
Source Phase Imports と足並みをそろえたリファクタリング的な Editorial Change が行われたのでその確認。具体的には新たに Module Source Records を定義し、Abstruct Module Records のフィールドとして追加された。これにより、今まではモジュールが JavaScript なのか WebAssembly かを都度調べていたのが、Module Source Records に集約された(PR#56)。
この提案で新しく追加される %AbstractModuleSource% と ModuleSource の確認。今までは ES Modules では Realm 内で URL アトリビュート (URL Key)の中身が一致していたら必ず同じインスタンスを返すようになっていた。しかし Module Source 自身の ID をベースにした Source Key が追加されることにより、Worker スレッドに ModuleSource を送りつけた場合に URL Key が一致していても同じインスタンスを返さないケースがある。
https://gyazo.com/9b4431f71535d04bc6b4a648429b6051
code: main.mjs
import source FooSource from "./foo.mjs";
const worker = new Worker("./worker.mjs", { type: "module" });
worker.postMessage(FooSource);
code: worker.mjs
import source FooSource2 from "./foo.mjs";
const FooSource = await new Promise((resolve) => {
self.addEventListener("message", (e) => {
resolve(e.data);
}, { once: true });
});
// 一致しない
console.log(await import(FooSource) !== await import(FooSource2));
この前提のもとで2つの Normative Change について議論された。
メインスレッドから Worker スレッドに同じ ModuleSource を2度送りつけた場合に、シリアライズ(構造化複製アルゴリズム)の観点から Worker スレッドで ModuleSource は別のオブジェクトになってしまうが、それらから作られるネームスペースオブジェクトは同じになる不整合がある。
https://gyazo.com/6ef537c538e6ed72f0b6b079fe2ffcfe
これは不自然だし、いっそのこと同じ [[SourceText]] から必ず同じインスタンスを返さないといけない制約をやめて、ModuleSource の JavaScript オブジェクトの同一性をもとに同じインスタンスを返すようにしてはどうかという Normative Change(PR#58)。
https://gyazo.com/19e7bfc088aa9734c922a1680f208df1
ちなみに(同一の Realm 内でも)ModuleSource を structuredClone しても別のインスタンスを返すようになる。
もう1つは、iframe や別提案の Compartments で Cross-Realm に ModuleSource のやりとりをした際の挙動を明確化した Normative Change(PR#61)。
結論は出ず、次回に持ち越し。
Error Stack Accessor for Stage 2.7 | Jordan Harband
Error.prototype.stack の標準化。現状各エンジンで own / prototype としてプロパティを持つかどうか、データ/アクセサプロパティとして持つかがバラバラになっているのを prototype のアクセサとして定める。
Stage 2.7 になった。
Iterator Includes for Stage 1, 2, or 2.7 (slides) | Michael Ficarra
Iterator.prototype.includes の提案。Array.prototype.includes 相当の明快な仕様であるということで、一気に Stage 2.7 になった。
Stage 2
RegExp Buffer Boundaries for Stage 2.7 (slides, test262 PR) | Ron Buckton
正規表現で ^ と $ が multiline (m) フラグを有効にした際に行頭、行末にマッチしてしまうため、あらたに \A と \z を追加する提案。Unicode (u, v)フラグが付いている場合にのみ有効となる。
十分なレビュー時間が確保できなかったので、Stage 2.7 昇格は次回に持ち越し。
JSON.parseImmutable update (slides) | Peter Klecha
Record & Tuple がなくなったけど、JSON.parseImmutable 自体は価値があるものとして残る。deeply frozen なプレーンオブジェクトを返す方向が支持されている。
Intl Unit Protocol for Stage 2 (slides) | Shane F Carr
Intl.NumberFormat で単位を後から指定できるようにする提案。今まで
code: js
let formatter = new Intl.NumberFormat(locale, {
style: "unit",
unit,
});
let result = formatter.format(value);
とコンストラクタ内で単位を指定する必要があったが、
code: js
let formatter = new Intl.NumberFormat(locale, {
style: "unit",
});
let result = formatter.format({
value,
unit,
});
が出来るようになる。
Stage 2 になった。
Thenable Curtailment for Stage 2 (Slides) | Matthew Gaudet
"then" のプロトタイプ汚染攻撃に対する防衛提案。新しく MaybeDeferredPromiseResolve を追加する。
実験として Moziila DOM チームの協力のもと WebIDL の the promies resolution steps を MaybeDeferredPromiseResolve に置き換えたときに Web Platform Tests の結果がどうなるかを Firefox で試した。ほとんど問題なかった。
これを Promise.resolve の安全版としてユーザーに提供するかどうか議論されている。
Stage 2 になった。
Stage 1
Intl Energy Units Stage 1 Update (slides) | Shane F Carr
新しい単位を追加する際には基準が必要ということが再認識された。
TypedArray concat for Stage 2 (slides) | James M Snell
%TypedArray% にスタティックメソッドとして concat を入れる提案。Iterable サポートを入れない方向で進もうとしており、函数名も別にする方針。
TypedArray find within for Stage 2 (slides) | James M Snell
Iterable サポートは切る方向。ShadowArrayBuffer 対応や、型不一致時に例外を出すかどうかがまだ詰めきれておらず、Stage 2 にならなかった。
Amount for Stage 2 (slides) | Ben Allen
単位換算機能が復活。丸めの扱いが主要論点。5月に Stage 2 を目指す。
First-class Protocols Update (slides) | Lea Verou
長いこと放置されていた protocol の提案。新しい champions group により再度進めることが共有された。
code: js
protocol Foldable {
requires foldr;
// provided members
toArray() {
return thisFoldable.foldr((m, a) => a.concat(m), []);
}
get length() {
return thisFoldable.foldr(m => m + 1, 0);
}
}
Symbol ファーストな設計や、implements の構文などが深堀りされた。必要な仕様の絞り込みを進める。
Error code property for Stage 1, 2, or 2.7 (slides) | James M Snell
Node.js などで Error インスタンスに付与される code プロパティでエラーの種類を出し分けている場合がある。これをコンストラクタのオプションとしてサポートする提案。
code: js
new Error("something went wrong", { code: "ERR_SOMETHING" })
Stage 1 になった。
Stage 0
N/A
Withdrawn
Withdraw Dynamic Import Host Adjustment | Steve Hicks
champion に継続意思がないことが確認され、廃止された。
その他
Abort Protocol Discussion | James M Snell
Web 標準側に移ってしまった中断についての仕様を言語側にも持たせたいということで支持された。
同期コールバック、コンビネーター、AbortSignal との整合性など、設計論点は多く残っている。
Tree-shakeable methods (slides) | Evan B Winslow
TC39 で Tree-shakeable methods のシンタックスを用意することで、バンドラーが要らないコードをより多く消せるのではという議論。どちらかといえばリンター/バンドラー側が解決する方が支持されたが、特に結論は出なかった。
test262 coverage strategies | Richard Gibson
normal completion に対して abrupt completion(例外が発生するケース)のテストが不十分であり、それを体系的に改善する試作が紹介された。
Toward structured concurrency (slides, repo for discussions) | Kevin Gibbons
AbortController/AbortSignal を拡張して structured concurrency に近づける道筋が提示された。
総括
8年11か月かかり Temporal が Stage 4 になった。仕様策定者、そしてエンジン実装者、polyfill 作者からのフィードバックなどなど多くの方が関わった結晶と言えると思う。
Explicit Resource Management が次回あたりで Stage 4 になりそうで嬉しい。
進行中の提案仕様としては ModuleSource の細かい挙動が詰められている。また "then" のプロトタイプ汚染に対抗する提案 Thenable Curtailment で Firefox を使った実験をしているのが面白い。
#ECMAScript