Goal

Reserve a space for static type syntax inside the ECMAScript language. JavaScript engines would treat type syntax as comments.

Before

ts
const message: string = "<h2> types"
console.log(message)
SyntaxError: Unexpected token ':'. const declared variable 'message' must have an initializer.
💥

After

ts
const message: string = "Hello, types"
console.log(message)
✅

The Types as Comments proposal aims to simplify working in a modern JavaScript codebase. With Types as Comments, developers can remove a build phase from their apps, keeping TypeScript and Flow codebases aligned with JavaScript. This proposal does not precisely specify a type syntax, which opens the door to many potential type systems in JavaScript.

How the proposal works

ts
const message = "Hello, types"
 
/* Echo the message */
console.log(message)
Hello, types

Today, a JavaScript engine knows that a backslash and a star (/*) indicates the start of a multi-line comment.

Which to the engine is roughly: 'from this point in the code move onwards ignoring the characters until you find a star with a backslash right after */' .

ts
const message: string = "Hello, types"
 
/* Echo the message */
console.log(message)
Hello, types

For the simplest case, the same idea could be applied to an engine which implements Type as Comments.

If the engine has just seen an identifier like 'message' and the next character is a colon (:), then treat the colon (:) and the next word of characters (': string') as a comment.

Once the engine hits the ='s then stop treating the code as comments and continue to create runtime code.

To the JavaScript runtime, the runtime code would look like this:

ts
const message = "Hello, types"
 
 
console.log(message)
Hello, types

The underlying implementation would need to be a more complex than that, for example to handle object literal syntax ({ id: string }) the engine would keep track of open and close braces.

The goal of the proposal is to provide a way to describe how to safely ignore type-like code inside the JavaScript language.

Who benefits?

JavaScript Users

Greatly reduces the need for source code transformation in modern JavaScript projects.

Cleaner and more powerful syntax than JSDoc comments.

Allows users of existing static type systems to migrate back towards source code alignment with JavaScript.

Pasting typed code into the console just works.

Tool Makers

New experimental type systems can be built using the ignored syntax space.

Existing JavaScript tools can:

Engine Maintainers

Browser engines do not pay any type-checking cost at runtime.

Engine maintainers avoid the burden of parser upgrades as each type system evolves.

Frequently Asked Questions

What type syntax is proposed?

Type definitions on functions and variable declarations, import/exporting types, class field and methods, generics, function overloads, `as X` type assertions, this parameters and more.

Will JavaScript engines perform type-checking?

No, the goal is to let projects like TypeScript, Flow and others provide the type system and check the code for type errors. JavaScript would only reserve a space in the JavaScript syntax for their type syntax to exist.

Will adding types slow down my JavaScript programs?

Like any new JavaScript feature, it would have performance trade-offs but the performance changes to JavaScript code would be is comparable to the performance hit in writing a comment in your code.

Basically, no

Will this grow JavaScript bundle sizes?

It could, but if you are already bundling then you would have the types removed during that bundling process. Negating the issue for most apps where bundle size is an concern.

JavaScript files without a build-step would have more characters as a result of the types. This is the same trade-off as adding comments to files, and the same solutions apply, e.g. use a minifier.

How does this differ from JSDoc support?

Today JavaScript users use JSDoc syntax with tooling in order to create a type-system in JavaScript code without a build step.

The syntax for JSDoc support is intentionally more verbose than type syntax, and is less ergonomic for complex typing as it is a documentation format. With this proposal, you can get JSDoc-like 'works without build tools' without the constraint of specially formatted comments.

Does this proposal favour TypeScript?

The proposal favors TypeScript/Flow-like syntax inside JavaScript, and is strongly influenced by syntax which is common to both language extensions. The aim is to also leave the door open for new syntax extensions which haven't been anticipated yet.

That said, the language in this specification favours TypeScript as it is the most popular type-system, but nearly all of the proposed syntax spaces would benefit Flow users too.

Is there prior art?

Python similarly implements support for opt-in type-checking. However this proposal has a stronger stance of relying solely on type erasure. Ruby is quite similar too.

Will this slow down JavaScript's evolution?

JavaScript's backwards compatibility goals of never breaking old code means that this is something future JavaScript syntax improvements would need to take into account. It is unlikely to get in the way of most new syntax however, as it is a strictly specified gap in the language instead of code which runs.

How does this affect runtime error messaging?

JavaScript today throws SyntaxError messages when it has evaluated invalid syntax. This will still be the same today, except for invalid code inside the areas designated for Types as Comments.

js
const mes sage: string = "Hello, types"
SyntaxError: Unexpected token ':'. const declared variable 'message' must have an initializer.

vs this 'error' in the types space:

ts
const message: { abc=123 } = "Hello, types"

Which would run perfectly fine in a JavaScript engine supporting this proposal, but fail in TypeScript or Flow. The proposal leaves type space errors to the IDE and type checker to declare the code inside the types are invalid, not the JavaScript runtime.

I'm new, what are these terms?

JavaScript is a language which does not provide a way to declare the input/outputs of your code. For example in JavaScript a let variable can be set to a string, number, object or more.

JavaScript extensions like TypeScript and Flow exist to add new syntax which have a way to declare 'this let variable can only be a string.'

The value in adding these extra definitions is that tooling can make better assumptions about how your code works and doesn't. That tooling can live in your IDE, or be a command-line app.

The process of verifying these assumptions is called type checking, and for JavaScript there are different type checkers with different trade-offs about how JavaScript code can be validated.

Prior to this proposal, you needed a tool like Babel or TypeScript to remove those definitions, after this proposal you do not need a build tool to remove them.

Removing this step can help simplify working in JavaScript projects to the point where you may not need any build tooling at all.

TypeScript Specific Frequently Asked Questions

Will all of TypeScript be supported by this proposal

No, not all of today's TypeScript syntax would be supported by this proposal. This is similar to how Babel support for TypeScript does not support all of the existing TypeScript syntax.

For example enums, namespaces and class parameter properties are unlikely to be supported.

How could I convert my TypeScript codebase to Types as Comments JavaScript?

It's likely that TypeScript will have a tsconfig flag which indicates that you want your files to be given the additional constraints imposed by Types as Comments.

This means you can migrate your code incrementally as .ts files before converting them to .js files.

How does this differ from JSDoc support?

JSDoc tried to solve the same problem as this proposal by the type information actually inside comments! Given the constraints of not being able to change the JavaScript language, this was a good compromise between wanting the code to be regular JavaScript while still type checking it via the TypeScript checker.

This proposal has no such constraints, and thus does not need to compromise. This proposal allows you to have the cake ("It's just JavaScript") and eat it too ("I want to check the types"). You get all the benefits of TypeScript's JSDoc support, but without the awkward syntax.

Do I need to migrate?

No, TypeScript has backwards compatibility guarantees which means you can continue to use .ts and .tsx files for TypeScript.

Links

Motivations

How does this proposal improve the JavaScript ecosystem as a whole?

Supported Syntax

From types definitions to class properties, see all the proposed supported type-level syntax.

Frequently Asked Questions

How does this proposal relate to TypeScript or Flow support? and many other questions.