Skip to content

[Bug]: Static property initialization with computed Symbol keys fails when class has a constructor #9121

@volkanceylan

Description

@volkanceylan

Reproduction link or steps

You may see the repository with reproduction at:

https://github.com/volkanceylan/vite8-static-init-issue

I changed the sample source so that only rolldown is used.

What is expected?

When bundling TypeScript classes with static properties that use computed keys (e.g., static [Symbol.toPrimitive] = "test"), rolldown incorrectly omits the initialization code for the computed key variable if the class also has a constructor. This results in the static property not being set at runtime.

Steps to Reproduce

Create a TypeScript file with a class that has a static property using a computed Symbol key and a constructor:

with-constuctor.ts:

export class SampleClass {
    static [Symbol.toPrimitive] = "test"

    constructor() {
    }
}

console.log("SampleClass[Symbol.toPrimitive]:", SampleClass[Symbol.toPrimitive]);

Bundle the code using rolldown and the output is like following:

dist/with-constructor.js

//#region with-constructor.ts
let _Symbol$toPrimitive;
var SampleClass = class {
	static {
		this[_Symbol$toPrimitive] = "test";
	}
	constructor() {}
};
console.log("SampleClass[Symbol.toPrimitive]:", SampleClass[Symbol.toPrimitive]);
//#endregion
export { SampleClass };

Note that let _Symbol$toPrimitive is not initialized anywhere.

If you simply remove the constructor:

without-constuctor.ts:

export class SampleClass {
    static [Symbol.toPrimitive] = "test"
}

console.log("SampleClass[Symbol.toPrimitive]:", SampleClass[Symbol.toPrimitive]);

The output is now correct:

//#region without-constructor.ts
let _Symbol$toPrimitive;
var SampleClass = class {
	static {
		_Symbol$toPrimitive = Symbol.toPrimitive;
	}
	static {
		this[_Symbol$toPrimitive] = "test";
	}
};
console.log("SampleClass[Symbol.toPrimitive]:", SampleClass[Symbol.toPrimitive]);
//#endregion
export { SampleClass };

Note the first static initialization block which was missing from the constructor case.

What is actually happening?

Static initialization block that sets _Symbol$toPrimitive variable is missing if the class has a constructor so the property is undefined.

System Info

rolldown 1.0.0-rc.15
node 24.10.0
nom 11.1.1

Any additional comments?

I noticed this bug while trying vite8 with vitest, and thought the problem is with vitest or vite8 ssr, and opened an issue there, but seems like it is at rolldown level, so I closed that one and reopening here.

Metadata

Metadata

Assignees

Type

Priority

None yet

Effort

None yet

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions