What’s Next for JavaScript? Inside TC39’s Latest Proposals and Stage Progress
The 2020 TC39 meeting reviewed several ECMAScript proposals—including Error Cause, Module Blocks, Extensions, and Grouped Accessor—detailing their motivations, required champion work, and code examples, while noting that no proposal advanced to a higher stage during the session.
This TC39 meeting was the final full assembly of 2020, and none of the discussed proposals achieved consensus to move from Stage 2 to Stage 3 or from Stage 3 to Stage 4.
Stage 1 → Stage 2
Advancing a proposal from Stage 1 to Stage 2 requires completing a draft of the standard text that contains the entire proposal.
Error Cause
Proposal link: https://github.com/tc39/proposal-error-cause Specification link: https://tc39.es/proposal-error-cause/
The proposal adds an optional cause parameter to the Error constructor, accepting any JavaScript value and assigning it to the cause property. Similar concepts exist in C#, Java, and Python, and libraries like verror and @netflix/nerror already use this pattern. With the proposal, developer tools can automatically display the cause value, improving debugging.
try {</code><code> return await fetch('//unintelligible-url-a')</code><code> .catch(err => {</code><code> throw new Error('Download raw resource failed', err)</code><code> })</code><code>} catch (err) {</code><code> console.log(err)</code><code> console.log('Caused by', err.cause)</code><code> // Error: Upload job result failed</code><code> // Caused by TypeError: Failed to fetch</code><code>}Stage 0 → Stage 1
Requirements to move a proposal from Stage 0 to Stage 1:
Find a TC39 member to act as champion.
Clearly define the problem, need, and a rough solution.
Provide examples of the problem and solution.
Discuss and analyze API shape, key algorithms, semantics, and implementation risks.
JavaScript Module Blocks
Proposal link: https://github.com/tc39/proposal-js-module-blocks
With many cores and workers (Web Workers, Node.js worker_threads, etc.), JavaScript lacks an ideal way to share code across execution units. Existing approaches either duplicate code or suffer from performance and security issues. This proposal introduces isolated module blocks that are parsed once and can be reused safely.
let workerCode = module {</code><code> onmessage = function({ data }) {</code><code> let mod = await import(data);</code><code> postMessage(mod.fn());</code><code> };</code><code>};</code><code>let worker = new Worker(workerCode, { type: 'module' });</code><code>worker.onmessage = ({ data }) => alert(data);</code><code>worker.postMessage(module { export function fn() { return 'hello!' } });Extensions
Proposal link: https://github.com/hax/proposal-extensions
Building on earlier proposals like the Pipeline and Bind operators, Extensions introduces local-scope extensions and accessors, providing a high‑productivity, isolated mechanism for augmenting objects without monkey‑patching.
Introduce local‑scope methods and accessor extensions for any JavaScript value.
Define a separate namespace for extensions to avoid clashes with ordinary variables.
Example declarations:
// Define a toSet method for collection types</code><code>const ::toSet = function () { return new Set(this) }</code><code>// Add an allDivs accessor to DOM objects</code><code>const ::allDivs = function {</code><code> get() { return this.querySelectorAll('div') }</code><code>}</code><code>let classCount = document</code><code> ::allDivs</code><code> ::flatMap(element => element.classList)</code><code> ::toSet()</code><code> ::sizeExtensions also support importing declarations from modules or using the namespaceOrConstructor:method syntax for quick access.
import ::{ identity } from 'some-module'</code><code>arrayLike</code><code> ::Array:map(x => x)</code><code> ::identity()Grouped Accessor
Proposal link: https://github.com/rbuckton/proposal-grouped-and-auto-accessors
Originating from Microsoft, this proposal allows getters and setters to be declared together, simplifying field accessor syntax and enabling more ergonomic decorator usage.
class C {</code><code> x {</code><code> get() { /* ... */ }</code><code> set(value) { /* ... */ }</code><code> }</code><code>}</code><code>const obj = {</code><code> x {</code><code> get() { /* ... */ }</code><code> set() { /* ... */ }</code><code> }</code><code>};</code><code>class D {</code><code> @logger()</code><code> x {</code><code> get() { /* ... */ }</code><code> set(value) { /* ... */ }</code><code> }</code><code>}While the proposal sparked extensive discussion, it ultimately entered Stage 1.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
