What Microsoft’s ES Type Syntax Proposal Means For JavaScript


Illustration showing the JavaScript logo

JavaScript could soon have its own type syntax if a proposal submitted by Microsoft and other developers earlier this year becomes a part of the ECMAScript standard. The initiative plans to add “types as comments” support to the JavaScript language, letting developers annotate code with type information that’ll be used by other ecosystem components.

The Syntax

The proposed syntax looks like this:

function sayAge(name: string, age: number) {
    console.log(`${name} is ${age} years old.`);
}
 
sayAge("JavaScript", 26);

It’ll be familiar to anyone who’s previously used TypeScript, Microsoft’s typed superset of JavaScript. TypeScript has gained widespread adoption across the industry; this new proposal purports to bring some of its benefits to the wider JavaScript world.

What Isn’t The Proposal?

If it gets approved, this proposal will let you write perfectly valid JavaScript with the type annotations shown above. It’ll be accepted by JavaScript runtimes such as web browsers, Node.js, and Deno that respect the ES standard.

The proposal doesn’t actually extend the JavaScript language though. Your type annotations will be exactly that: inert metadata that have no effect on the JavaScript compiler or your code’s runtime. A function call such as the following would work at runtime:

function sayAge(name: string, age: number) {
    console.log(`${name} is ${age} years old.`);
}
 
// "age" is a string when it should be a number, but this is still allowed
sayAge("JavaScript", "twenty");

The idea is to offer a new type syntax that’s officially supported but completely ignored by engines. The only change for implementations concerns recognizing and stripping out type annotations wherever they’re used.

The proposal would seek to establish support annotating the types of parameters, variables, and class properties. It’d also look at adding an interface keyword, assertion operators like ! and as, and a ? modifier to mark types as optional. The intention is for all these elements to mirror TypeScript; as with any Stage 0 proposal, the final outcome may work differently though.

What’s The Point?

If type annotations won’t change your program, the obvious question is whether they’re worth having. The proposal argues “yes” because of the syntax’s ability to shorten iteration times and reduce the burden around modern JavaScript toolchains.

Writing type-safe code currently requires you to use TypeScript, a different language flavor that adds dependencies to your project and necessitates a manual compilation step. That code may then pass through other tools such as a module bundler and transpiler before your final JavaScript is produced for distribution. It adds up to a complex toolchain with multiple moving parts.

Although JavaScript is an inherently loosely typed language, the benefits of strong typing are now broadly recognized by the community. This much is evident from the momentum surrounding the TypeScript project. Static typing was also the clear leader in the 2021 State of JS survey’s “missing feature” question.

Adding a type syntax to JavaScript itself would let you get some of the benefits of TypeScript without having to compile your code. This simplifies project set up and maintenance while evolving JavaScript to better align with modern development practices.

Over the past several years, more code has begun to migrate back towards a “pure JavaScript” approach. The decline of legacy browsers makes transpilation less necessary than it once was – the majority of modern implementations offer full support for features like classes, arrow functions, block-scoped variables, and async/await. JavaScript’s even got a fully-fledged module system that works across engines, including in browsers.

Only a few years ago a lengthy toolchain was required to be able to write these features into your code with confidence it would work on users’ devices. Nowadays developers can safely put those build processes aside, returning to the original JavaScript model of referencing files with <script> tags.

Types are one of the few remaining areas of the JavaScript ecosystem that aren’t accommodated by the language itself. Love them or hate them, there’s no denying that types have become an integral part of JavaScript development for many teams and projects. The syntax proposal formally recognizes this fact. It attempts to bring a degree of type support to JavaScript without breaking existing code or enforcing performance-hitting runtime type checks.

What Should Types Actually Do?

The role of a “type” varies between languages. The common demoninator lies in a type’s ability to express the type of data a particular variable will hold. Additional meanings, capabilities, and behaviors are then layered on that foundation.

In statically typed compiled languages like C# and Java, types are enforced at compilation time. It’s impossible to compile a program when you’ve got type incompatibilities in your code. In interpreted languages with optional strong typing, of which PHP is an example, types are enforced at runtime – the program throws an error when a value’s type is incompatible with the context in which it’s used.

An active debate within the JavaScript community has been how far any built-in type system’s remit should extend. This proposal limits its role to the most foundational element, a simple documentation of a value’s expected type. This aligns well with TypeScript’s position as an erasable type syntax that’s ignored at runtime.

The purpose of this model is to give developers instant feedback about potential bugs as they write code. You could get information about type issues as you write regular JavaScript in a compatible IDE. If you wanted to, you could also use a supporting tool such as TypeScript, a static analyzer, or a bundler to audit your source on-demand. This could block a deployment in your CI pipelines when a type issue is present.

The current feeling is that these capabilities are sufficient to align JavaScript with the most common developer needs. Features found in other languages such as introspection and reflection are not commonly needed within the JavaScript ecosystem, in part because developers have become used to TypeScript’s erasure approach.

The Existing Alternative: Docblocks

It’s worth noting that something similar to the proposed erased annotations syntax already exists: familiar JSDoc tags are commonly used to add type details to plain JavaScript code:

/**
 * @param name {string}
 * @param age {number}
 */
function sayAge(name, age) {
    console.log(`${name} is ${age} years old.`);
}

JSDoc comments are supported by various popular tools. However, they’re not a standardized part of the language and they require you to mix details of your code’s operation – its expected types – with the human-centric documentation comprising the rest of the docblock.

JSDoc’s syntax is also very verbose. Besides the required tag names, it typically requires repetition of elements already existing in your code, such as the parameter names in the example above. If you modify a parameter in the function’s signature, you must remember to change the JSDoc tag too.

The new syntax proposal may be functionally equivalent to docblocks but it offers a much more streamlined experience. Types sit alongside their targets as part of your source, instead of in a docblock that you need to separately author and maintain.

What’s Next?

Microsoft’s TypeScript team and co-authors including Bloomberg, Igwalia, and several independent contributors submitted the Stage 0 proposal in the March 2022 TC39 plenary. The proposal has since progressed into Stage 1. Acceptance is still some way off though, with implementation inside engines potentially not arriving for “years.”

The overarching objective of this proposal is to balance JavaScript’s long tail of untyped code with the current demand for a more statically typed development experience. The use of an erased fully optional syntax guarantees backwards compatibility but raises the prospect that it’ll be ineffective at encouraging adoption and consolidating the ecosystem. The debate around this one looks set to grow with new opinions and perspectives as the proposal progresses through the standards track.





Source link