Fundamentals 19 min read

TC39 Updates: Error Cause, Intl.DisplayNames, Import Assertions & More

The article reviews the latest TC39 meeting, detailing proposals that moved to higher stages—including Error Cause reaching Stage 4, Intl.DisplayNames enhancements, Import Assertions, .item() for indexables, class static blocks, resizable array buffers, Intl.Enumeration, double‑ended iterators, integer math extensions, standardized debug syntax, String.dedent, Intl.Locale, and DisplayNames v2—while outlining the criteria required for each stage transition.

Node Underground
Node Underground
Node Underground
TC39 Updates: Error Cause, Intl.DisplayNames, Import Assertions & More

Stage 3 → Stage 4

To advance from Stage 3 to Stage 4 a proposal must provide TC39/test262 tests, have at least two implementations passing those tests, and submit a pull request to tc39/ecma262 that is signed off by the ECMAScript editor.

Intl.DisplayNames

The proposal adds internationalized names for common nouns such as region, script, language, and currency.

Region "region" can use an ISO‑3166 two‑letter code or a three‑digit UN M49 region code.

Script "script" must use an ISO‑15924 four‑character code.

Language "language" follows the UTS 35 Unicode Language and Locale Identifiers grammar (e.g., ISO 639‑1 or ISO 639‑2 codes).

Currency "currency" uses a three‑character ISO 4217 code.

// Get display name for Simplified Chinese region names
let regionNames = new Intl.DisplayNames(['zh-Hans'], {type: 'region'});
regionNames.of('US'); // "美国"
regionNames.of('419'); // "拉丁美洲"
regionNames.of('MM'); // "缅甸"

As a Stage 4 proposal, the features are already shipped in Chrome 81 and Node.js 14 without any flags.

The meeting also introduced an enhanced Intl.DisplayNames proposal at Stage 1.

Stage 2 → Stage 3

Advancing requires a complete standard text reviewed and signed by a TC39 member and the ECMAScript editor.

.item() for indexables

Proposal link: tc39/proposal-item-method Spec text: item()

The proposal adds .item() to Array/TypedArray and to String.prototype, providing the same semantics as indexed access but also supporting reverse indexing, e.g., arr.item(-1) returns the last element.

Import Assertions

Proposal link: tc39/proposal-import-assertions Spec text: import assertions

The proposal adds an assert clause to import statements, allowing developers to declare the expected module type (e.g., JSON) and avoid security problems caused by MIME‑type based module loading.

import json from "./foo.json" assert { type: "json" };
import("foo.json", { assert: { type: "json" } });

JSON module semantics are defined in a separate Stage 2 proposal.

Stage 1 → Stage 2

Moving to Stage 2 requires drafting the full standard text for the proposal.

Class static initialization block

Proposal link: tc39/proposal-class-static-block Spec text: class static initialization blocks

The proposal introduces static blocks that execute when a class is evaluated. They have access to private fields, enabling patterns such as friend classes.

let A, B;
{ let friendA;
  A = class A { #x; static { friendA = { getX(o){ return o.#x }, setX(o,v){ o.#x = v } }; };
  B = class B { constructor(a){ const x = friendA.getX(a); friendA.setX(a, value); } };
}
export { A, B };

ResizableArrayBuffer and GrowableSharedArrayBuffer

Proposal link: tc39/proposal-resizablearraybuffer Spec text: ResizableArrayBuffer and GrowableSharedArrayBuffer

These proposals add two new ArrayBuffer types for WebAssembly scenarios. ResizableArrayBuffer can be resized in place, while GrowableSharedArrayBuffer can grow across multiple agents but cannot shrink.

let rab = new ResizableArrayBuffer(1024, 1024**2);
assert(rab.byteLength === 1024);
assert(rab.maximumByteLength === 1024**2);
rab.resize(rab.byteLength * 2);
assert(rab.byteLength === 2048);

Intl.Enumeration

Proposal link: tc39/proposal-intl-enumeration Spec text: Intl Enumeration API Specification

The proposal provides APIs to enumerate supported calendars, currencies, numbering systems, time zones, units, etc.

// Get supported calendars
Intl.getSupportedCalendars(); // ["buddhist","chinese","coptic",...]

Stage 0 → Stage 1

Requirements: a champion TC39 member, a clear problem statement and solution, concrete examples, and analysis of API shape, algorithms, semantics, and implementation risk.

Error Cause

Proposal link: tc39/proposal-error-cause

The proposal adds an optional cause argument to the Error constructor, enabling error chaining and allowing dev tools to display the underlying cause.

try {
  return await fetch("//unintelligible-url-a")
    .catch(err => { throw new Error("Download raw resource failed", err); });
} catch (err) {
  console.log(err);
  console.log("Caused by", err.cause);
  // Error: Download raw resource failed
  // Caused by TypeError: Failed to fetch
}

Double‑Ended Iterator & Destructuring

Proposal link: tc39/proposal-deiter

The proposal defines a bidirectional iterator that can be used with destructuring to extract elements from both ends of an iterable.

let [first, ...rest, last] = iterable; // using a double‑ended iterator

Modulus & Additional Integer Math

New Math methods for precise integer arithmetic: Math.mod(x, y) – IEEE 754 modulus. Math.idiv(x, y) – 32‑bit integer division. Math.imod(x, y) – 32‑bit integer modulus. Math.idivmod(x, y) – returns [quotient, remainder]. Math.imuldiv(x, y, z) – computes (x * y) / z with a 64‑bit intermediate. Math.irem(x, y) – 32‑bit integer remainder.

Standardized Debug

Proposal link: tc39/proposal-standardized-debug

The proposal suggests a dbg! syntax (or an extension of debugger) to print intermediate values without extra boilerplate.

function doSomething(a) {
  let b = dbg!(a + costlyOperation()) * 2;
  // ...
}

String Dedent

Proposal link: tc39/proposal-string-dedent

Introduces String.dedent to automatically remove common leading whitespace from template literals.

class Foo {
  methodA() {
    const foo = String.dedent(`
      First Line
      Second Line
      Third Line`);
    return foo;
  }
}

Intl Locale

Proposal link: tc39/proposal-intl-locale-info

Provides properties such as firstDayOfWeek, minimalDaysInFirstWeek, weekendStart, weekendEnd, direction, measurementSystem, defaultHourCycle, defaultCalendar, and commonCalendars on Intl.Locale.prototype.

Intl.DisplayNames v2

Proposal link: tc39/intl-displaynames-v2

Extends Intl.DisplayNames to support months, weekdays, units, time zones, calendars, and numbering systems.

let dn = new Intl.DisplayNames("zh-Hans", {type: "month", style: "long"});
console.log(dn.of(1)); // "1月"
let dnEn = new Intl.DisplayNames("en", {type: "month", style: "long", calendar: "coptic"});
console.log(dnEn.of(1)); // "Tout"

Summary

Standardizing language features is an incremental process; many proposals need community feedback to progress through TC39 stages, and active participation from JavaScript developers is essential.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Error HandlingTC39intlECMAScript proposalsImport Assertions
Node Underground
Written by

Node Underground

No language is immortal—Node.js isn’t either—but thoughtful reflection is priceless. This underground community for Node.js enthusiasts was started by Taobao’s Front‑End Team (FED) to share our original insights and viewpoints from working with Node.js. Follow us. BTW, we’re hiring.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.