Repository: sveltejs/svelte (2025-07-30T19:32:21Z)

Issue:
duplicate_class_field false positive with static class members
### Describe the bug

``` ts
class Hello {
  hello() {}
  static hello() {} // throws "`hello` has already been declared"
}
```

### Reproduction

https://svelte.dev/playground/d875318270e444efb8a4e7b095375885?version=5.37.1

### Logs

```shell

```

### System Info

```shell
System:
    OS: macOS 15.5
    CPU: (8) arm64 Apple M1
    Memory: 130.66 MB / 8.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.17.0 - ~/.nvm/versions/node/v20.17.0/bin/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v20.17.0/bin/yarn
    npm: 10.8.2 - ~/.nvm/versions/node/v20.17.0/bin/npm
    bun: 1.0.15 - ~/.bun/bin/bun
    Watchman: 2023.12.04.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome: 138.0.7204.170
    Safari: 18.5
```

### Severity

annoyance


Discussion:

Patch:
diff --git a/.changeset/nine-cups-film.md b/.changeset/nine-cups-film.md
new file mode 100644
index 000000000000..ba72337daca7
--- /dev/null
+++ b/.changeset/nine-cups-film.md
@@ -0,0 +1,5 @@
+---
+'svelte': patch
+---
+
+fix: correctly differentiate static fields before emitting `duplicate_class_field`
diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/ClassBody.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/ClassBody.js
index 2bfc1dbce36c..dd216371740c 100644
--- a/packages/svelte/src/compiler/phases/2-analyze/visitors/ClassBody.js
+++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/ClassBody.js
@@ -57,7 +57,7 @@ export function ClassBody(node, context) {
 				e.state_field_duplicate(node, name);
 			}
 
-			const _key = (key.type === 'PrivateIdentifier' ? '#' : '') + name;
+			const _key = (node.type === 'AssignmentExpression' || !node.static ? '' : '@') + name;
 			const field = fields.get(_key);
 
 			// if there's already a method or assigned field, error
@@ -78,7 +78,7 @@ export function ClassBody(node, context) {
 	for (const child of node.body) {
 		if (child.type === 'PropertyDefinition' && !child.computed && !child.static) {
 			handle(child, child.key, child.value);
-			const key = (child.key.type === 'PrivateIdentifier' ? '#' : '') + get_name(child.key);
+			const key = /** @type {string} */ (get_name(child.key));
 			const field = fields.get(key);
 			if (!field) {
 				fields.set(key, [child.value ? 'assigned_prop' : 'prop']);
@@ -91,7 +91,7 @@ export function ClassBody(node, context) {
 			if (child.kind === 'constructor') {
 				constructor = child;
 			} else if (!child.computed) {
-				const key = (child.key.type === 'PrivateIdentifier' ? '#' : '') + get_name(child.key);
+				const key = (child.static ? '@' : '') + get_name(child.key);
 				const field = fields.get(key);
 				if (!field) {
 					fields.set(key, [child.kind]);


Test patch:
diff --git a/packages/svelte/tests/validator/samples/class-state-constructor-9/input.svelte.js b/packages/svelte/tests/validator/samples/class-state-constructor-9/input.svelte.js
index a8469e13af46..3806046f3f72 100644
--- a/packages/svelte/tests/validator/samples/class-state-constructor-9/input.svelte.js
+++ b/packages/svelte/tests/validator/samples/class-state-constructor-9/input.svelte.js
@@ -1,6 +1,6 @@
 export class Counter {
 	count = -1;
-
+	static count() {}
 	constructor() {
 		this.count = $state(0);
 	}