Changelog: swc v1.2.52

Bugfixes#

external helper: typeof (#1557, #1458)#

Previously swc used incorrect name for typeof helpers, if extenalHelpers is true.

{
"jsc": {
"externalHelpers": true,
"target": "es2015"
}
}

This is now fixed.

helper bugs (#1555)#

Some helpers were compiled incorrectly due to a bug of the resolver pass.

The bug made swc to emit

function _setPrototypeOf(o, p) {
_setPrototypeOf =
Object.setPrototypeOf ||
function _setPrototypeOf1(o1, p1) {
o1.__proto__ = p1;
return o1;
};
return _setPrototypeOf1(o, p);
}
exports.default = _setPrototypeOf;

for

export default function _setPrototypeOf(o, p) {
_setPrototypeOf =
Object.setPrototypeOf ||
function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}

This is now fixed.

CR in template literals (#1549)#

Previously the code below resulted in a bug.

const { transform } = require("@swc/core");
transform("const a = `\r\n`;", {
jsc: {
parser: {
syntax: "typescript",
},
target: "es2015",
},
})
.then(({ code }) => code)
.then(console.log, console.error);

Input sourcemap bug (#1404)#

swc now handles input source map correctly.

Generic parsing bug (#1526)#

export const foo = function* <T>() {};
export const bar = () => {};

Prevously swc incorrectly failed emitting invalid syntax error. It was due to <T> being parsed as jsx and it's now fixed.

Dead branch remover bug (#1539)#

function test() {
return foo();
function foo() {
return 2;
}
console.log("hi");
}

is now compiled as

function test() {
function foo() {
return 2;
}
return foo();
}

Fixed by @devongovett.

TypeScript namespace bug (#1553, #1515)#

export function a() {}
export namespace a {
export function b() {}
}

When a typescript namespace is used with another declaration with identical name, swc produced an invalid code. It's now fixed by tracking names.

Sourcemap position bug (#1548)#

It's reported via deno.

swc emitted 0 for the column of indented nodes, which made the sourcemap unhelpful. swc now considers indention while emiiting sourcemap.

Visitor bug (#1543)#

There was a change to ast because previous design did not allow getting span of the template part of the template literal. But the node package was not updated and it's fixed by this pr.

Fixed by @arendjr.

Resolver bug relatead to function expressions (#1540)#

Previously swc compiled

export default function foo() {
foo = function foo(x) {
return x === 0 ? 1 : 1 + foo(x - 1);
};
return foo(10);
}

as

export default function foo() {
foo = function foo1(x) {
return x === 0 ? 1 : 1 + foo1(x - 1);
};
return foo1(10); // <- this is wrong
}

which is wrong.

The bug is fixed by @devongovett and swc now emits

test(function foo() {
foo = function foo1(x) {
return x === 0 ? 1 : 1 + foo1(x - 1);
};
return foo(10);
});

TypeScript definitions (#1542, #1535)#

Some AST type definitions are wrong, and it's now fixed by @wavesheep.

Branch simplifier bug (#1536)#

Previously the optimizer of swc broke codes like

if (Date.now() < 0) {
for (let i = 0; i < 10; i++) {
if (Date.now() < 0) {
console.log(1);
}
}
} else {
console.log(2);
}

It's now fixed by @devongovett.

TypeScript common js import bug (#1448)#

swc now supports common js import of typescript.

import F = require("yaml");
console.log(F);

Default destructuring patterns (#1477, #1449)#

swc now supports default patterns in object patterns.

async function foo() {
const { bar: {} = {} } = baz;
}

this in async object methods (#1455)#

swc previously broke codes with asynchronous method like

const SampleData = typedModel(
"SampleVideo",
VideosSchema,
undefined,
undefined,
{
byPlatform: async function (platform: string) {
const result = await this.find({ platform: { $eq: platform } });
return result;
},
}
);
SampleData.byPlatform("youtube").then((res) => {
console.info(res);
});

It's now fixed.

Type stripper bug (#1521)#

swc now allows declaring a type with name which is imported.

For example code below,

import { Test } from "test";
interface Test {}
console.log(Test);

import { Test } from "test"; is now preserved because console.log(Test); uses Test.

Fixed by @devongovett.

Comment parsing bug (#1527)#

function Bar() {
const [foo, setFoo] = useState(0);
React.useEffect(() => {
// @refresh reset
});
return <h1>{foo}</h1>;
}

swc now handles comment // @refresh reset correctly.

Abstract classes (#1454)#

export abstract class AbstractProviderDeliveryService {}

Super in class methods (#1490)#

There were some edge cases where swc emits wrong code for usages of super in class methods.

Affected code looks like

"use strict";
class Element {
getChildElements() {
return this.childElements;
}
}
class CanvasElement extends Element {
createFacets(hidden) {
const childElements = this.getChildElements();
///
}
}
class ColouredCanvasElement extends CanvasElement {
createFacets(hidden) {
hidden = super.createFacets(hidden); /// This line was buggy
///
}
}
class ColouredSquare extends ColouredCanvasElement {}
const bugExample = () => {
const colouredSquare = new ColouredSquare(),
hidden = false;
colouredSquare.createFacets(hidden);
};
export default bugExample;

Backticks in template literals (#1488)#

Previously swc handled

`\``;

in a wrong way. It's now fixed.

Declare namespace bug (#1508)#

swc preivously didn't handle declare namespace correctly. It emitted

var twttr;
(function (twttr1) {
const txt;
twttr1.txt = txt;
})(twttr || (twttr = {}));

for

declare namespace twttr {
export const txt: typeof import("twitter-text");
}

which should be an empty file. It's now fixed.

ES module interop for dynamic imports (#1480, #1509)#

Code like

const { default: ora } = await import("ora");

requires some helpers to work properly, but swc didn't use helpers.

It's now fixed and it works identically as tsc.

Parenthesis bug of class properties (#1502)#

Previously swc compiled

class A {
a = (console.log(1), 2);
}

as

class A {
a = console.log(1), 2;
}

but it's now

class A {
a = (console.log(1), 2);
}

Fixed by @nayeemrmn

Sourcemaps of multiline block comments (#1511)#

Before: Before

After: After

Fixed by @devongovett.

Generic parsing bug (#1505)#

swc has a bug related to backtracking and as a result the following code result in an exception.

type InjectedTeamsProps = {};
class Component<_T, _U> {}
class ComponentType<_T> {}
const withTeamsForUser = <P extends InjectedTeamsProps>(
_WrappedComponent: ComponentType<P>
) =>
class extends Component<
Omit<P, keyof InjectedTeamsProps> & Partial<InjectedTeamsProps>,
InjectedTeamsProps
> {
static displayName = `x`;
};

This is fixed.

Class names when keepClassNames is true (#1507)#

Previously keepClassNames didn't work for class expressions. This resulted in decorated class declarations being renamed, which breaks codes depend on relfect-metadata.

Affected code looks like:

import { Entity, BaseEntity } from "typeorm";
@Entity()
export class Location extends BaseEntity {}

Class properties named readonly (#1514)#

swc now supports

export class ClassProp {
readonly!: boolean;
}

Private declare properties (#1503)#

class Class {
private declare prop;
}

The code above now works with swc.

Assert after imports (#1512)#

import assert from "./index";
assert<123>(123);
assert<123>(123, 123);
assert<123>(123, 123, 123);

For the code above, the parser of swc tried to eat second assert to parse it as a part of an import assertion. This is fixed by checking for newlines.

New features#

TypeScript 4.3#

override (#1541)#

class SpecializedComponent extends SomeComponent {
override show() {
// ...
}
override hide() {
// ...
}
}

Implemented by @g-plane.

See: https://devblogs.microsoft.com/typescript/announcing-typescript-4-3-beta/#override-and-the-noimplicitoverride-flag

getter / setters (#1517)#

interface X {
get foo(): string;
set foo(v: string | number);
}
type Y = {
get bar(): string;
set bar(v: string | number);
}

static index signature (#1537)#

class Foo {
static hello = "hello";
static world = 1234;
static [propName: string]: string | number | undefined;
}

Implemented by @g-plane.

See: https://devblogs.microsoft.com/typescript/announcing-typescript-4-3-beta/#static-index-signatures

Pure annotation for react (#1564)#

swc now emits /*#__PURE__*/ for react components, which is used by various optimizers to identify side-effect-free functions.

Implemented by @devongovett.

Fast refresh (#1524)#

swc now supports react fast refresh. See docs for configurations.

Implemented by @Austaras.

UX Improvement#

Better error message for wrong configurations. (#1532)#

Previously swc sielently used default syntax for the .swcrc below.

{
"jsc": {
"parser": {
"syntax": "typescript",
"dynamicImport": true
},
"externalHelpers": true,
"target": "esnext"
},
"sourceMaps": true
}

This config is invalid because target does not allow esnext. But error message was cryptic because it was about parsing failure.

It's now fixed and swc reports proper error for such inputs.

Parser error code (#1551)#

Previously swc emiited TS1775 for the code below, but it should be TS1773.

class C implements A extends B {}

Fixed by @g-plane