Skip to main content

7.12.0 Released: TypeScript 4.1, strings as import/export names, and class static blocks

· 4 min read

We just published a new minor version of Babel!

This release includes support for the new TypeScript 4.1 beta features: template literal types and key remapping in mapped types.

Additionally, we implemented two new ECMAScript proposals: class static blocks and imports and exports with string names.

Lastly, we renamed @babel/plugin-syntax-module-attributes (and the corresponding parser plugin moduleAttributes) to @babel/plugin-syntax-import-assertions (and importAssertions), to match the recent proposal updates. The old plugin will work until Babel 8, but it's deprecated now.

You can read the whole changelog on GitHub.

If you or your company want to support Babel and the evolution of JavaScript, but aren't sure how, you can donate to us on our Open Collective and, better yet, work with us on the implementation of new ECMAScript proposals directly! As a volunteer-driven project, we rely on the community's support to fund our efforts in supporting the wide range of JavaScript users. Reach out at team@babeljs.io if you'd like to discuss more!

Highlights

TypeScript 4.1 (#12129, #12131)

TypeScript 4.1 beta was announced a few weeks ago, and it includes new syntax features for types.

Template literal types allow concatenating strings at the type-level, using the template literal syntax:

type Events = "Click" | "Focus";

type Handler = {
[K in `on${Events}`]: Function
};

const handler: Handler = {
onClick() {}, // Ok
onFocus() {}, // Ok
onHover() {}, // Error!
};

Together with key remapping in mapped types, they can be used to represent complex object transformations:

type Getters<T> = {
[K in keyof T as `get${Capitalize<K>}`]: () => T[K]
};

interface Dog { name: string; age: number; }

const lazyDog: Getters<Dog> = /* ... */;
lazyDog.getName(); // string
lazyDog.age; // error!

You can read more about TypeScript 4.1 in the release announcement, or check other examples of what capabilities these new features unlock. However, remember that TypeScript 4.1 is still experimental!

Class static blocks (#12079, #12143)

Example on Babel REPL

JavaScript
class C {
static #x = 42;
static y;
static {
try {
this.y = doSomethingWith(this.#x);
} catch {
this.y = "unknown";
}
}
}

This stage 2 proposal allows you to apply additional static initializations when a class definition is evaluated. It is not intended to replace static fields but to enable new use cases that could not be accomplished before. In the example above, the static property y is initialized using #x. If doSomethingWith(this.#x) throws, y will be assigned by a default value "unknown".

You can read more about it in the proposal's description.

Thanks to Jùnliàng, you can test this proposal by installing the @babel/plugin-proposal-class-static-block plugin and adding it to your Babel config. Since it is likely you're already using other class feature plugins, be sure to place this plugin before the others:

babel.config.json
{
"plugins": [
"@babel/plugin-proposal-class-static-block",
"@babel/plugin-proposal-class-properties"
]
}
note

Babel implements an updated version of spec, which addresses feedback we have provided based on the current spec.

Imports and exports with string names (#12091)

Consensus was achieved during the last TC39 meeting with a PR to allow strings as the name of imported and exported variables:

JavaScript
// emojis.js
let happy = "wooo!";
export { happy as "😃" };

// main.js
import { "😃" as smile } from "./emojis.js";
console.log(smile); // wooo!

This allows using any valid UTF-16 name across modules, making JavaScript fully compatible with other languages such as WebAssembly.

You can enable parsing support for this feature by adding @babel/plugin-syntax-module-string-names to your configuration:

babel.config.json
{
"presets:" ["@babel/preset-env"],
"plugins": [
"@babel/syntax-module-string-names"
]
}

This feature will be enabled by default as soon as the syntax is merged into the main ECMAScript specification.

Please note that it's not possible to transpile arbitrary strings to ES2015-style imports and exports: they will only be transpiled when targeting a different modules system such as CommonJS.

Import assertions parsing (#12139)

The "module attributes" proposal has been significantly changed and also renamed to "import assertions".

We've implemented parsing support for this new version of the proposal, which can be enabled using the @babel/plugin-syntax-import-assertions plugin (or, if you are directly using @babel/parser, importAssertions):

 {
"plugins": [
- ["@babel/syntax-module-attributes", { "version": "may-2020" }]
+ "@babel/syntax-import-assertions"
]
}

The most significant syntax changes are that the with keyword has been replaced with assert and assertions are now wrapped in curly braces:

JavaScript
import json from "./foo.json" assert { type: "json" };

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

You can read more about these changes in the proposal's README.

caution

@babel/plugin-syntax-module-attributes will continue working until we release Babel 8.0.0, but will no longer be maintained, so we highly recommended migrating to the new plugin.