# Breaking changes in v20

This release bumps `@open-turo/eslint-config-typescript` to v20.x. The following breaking changes cascade from that dependency (newest first).

## v20.1.0 - Perfectionist Rule Overrides (2026-03-09)

- `perfectionist/sort-classes`: Uses explicit groups for class member ordering instead of alphabetical.
- `perfectionist/sort-switch-case` and `perfectionist/sort-union-types`: Changed from alphabetical to natural sort order.

```diff
diff --git a/test/__snapshots__/test.spec.js.snap b/test/__snapshots__/test.spec.js.snap
--- a/test/__snapshots__/test.spec.js.snap
+++ b/test/__snapshots__/test.spec.js.snap
@@ -1359,8 +1359,84 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   "perfectionist/sort-classes": [
     2,
     {
-      "order": "asc",
-      "type": "alphabetical",
+      "groups": [
+        "index-signature",
+        [
+          "static-property",
+          "static-accessor-property",
+        ],
+        [
+          "static-get-method",
+          "static-set-method",
+        ],
+        [
+          "protected-static-property",
+          "protected-static-accessor-property",
+        ],
+        [
+          "protected-static-get-method",
+          "protected-static-set-method",
+        ],
+        [
+          "private-static-property",
+          "private-static-accessor-property",
+        ],
+        [
+          "private-static-get-method",
+          "private-static-set-method",
+        ],
+        "static-block",
+        [
+          "property",
+          "accessor-property",
+        ],
+        [
+          "protected-property",
+          "protected-accessor-property",
+        ],
+        [
+          "private-property",
+          "private-accessor-property",
+        ],
+        "constructor",
+        [
+          "get-method",
+          "set-method",
+        ],
+        [
+          "protected-get-method",
+          "protected-set-method",
+        ],
+        [
+          "private-get-method",
+          "private-set-method",
+        ],
+        [
+          "static-method",
+          "static-function-property",
+        ],
+        [
+          "protected-static-method",
+          "protected-static-function-property",
+        ],
+        [
+          "private-static-method",
+          "private-static-function-property",
+        ],
+        [
+          "method",
+          "function-property",
+        ],
+        [
+          "protected-method",
+          "protected-function-property",
+        ],
+        [
+          "private-method",
+          "private-function-property",
+        ],
+        "unknown",
+      ],
     },
   ],
@@ -1471,15 +1471,13 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   "perfectionist/sort-switch-case": [
     2,
     {
-      "order": "asc",
-      "type": "alphabetical",
+      "type": "natural",
     },
   ],
   "perfectionist/sort-union-types": [
     2,
     {
-      "order": "asc",
-      "type": "alphabetical",
+      "type": "natural",
     },
   ],
```

(Similar changes apply to index.mjs and legacy recommended config.)

## v20.0.0 - Strict Type-Checked and Legacy Config Parity (2026-03-06)

- Flat config now enforces `strictTypeChecked` instead of `recommendedTypeChecked`, enabling additional @typescript-eslint rules that may raise new errors.
- eslint/recommended v9 rule changes backported to legacy config — rules previously off are now errors (constructor-super, getter-return, no-dupe-\*, no-undef, no-unused-vars, etc.).
- Some unicorn rules disabled: empty-brace-spaces, no-nested-ternary, number-literal-case, template-indent.

```diff
diff --git a/test/__snapshots__/test.spec.js.snap b/test/__snapshots__/test.spec.js.snap
--- a/test/__snapshots__/test.spec.js.snap
+++ b/test/__snapshots__/test.spec.js.snap
@@ -553,6 +553,9 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   ],
   "@typescript-eslint/ban-ts-comment": [
     2,
+    {
+      "minimumDescriptionLength": 10,
+    },
   ],
@@ -619,6 +622,9 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   "@typescript-eslint/no-duplicate-type-constituents": [
     2,
   ],
+  "@typescript-eslint/no-dynamic-delete": [
+    2,
+  ],
@@ -646,18 +655,36 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   "@typescript-eslint/no-import-type-side-effects": [
     2,
   ],
+  "@typescript-eslint/no-invalid-void-type": [
+    2,
+  ],
+  "@typescript-eslint/no-meaningless-void-operator": [
+    2,
+  ],
   "@typescript-eslint/no-misused-new": [
     2,
   ],
   "@typescript-eslint/no-misused-promises": [
     2,
   ],
+  "@typescript-eslint/no-misused-spread": [
+    2,
+  ],
+  "@typescript-eslint/no-mixed-enums": [
+    2,
+  ],
@@ -673,6 +700,9 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   "@typescript-eslint/no-unnecessary-condition": [
     0,
   ],
+  "@typescript-eslint/no-unnecessary-template-expression": [
+    2,
+  ],
@@ -738,26 +777,57 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   "@typescript-eslint/prefer-as-const": [
     2,
   ],
+  "@typescript-eslint/prefer-literal-enum-member": [
+    2,
+  ],
   "@typescript-eslint/prefer-namespace-keyword": [
     2,
   ],
   "@typescript-eslint/prefer-promise-reject-errors": [
     2,
   ],
+  "@typescript-eslint/prefer-reduce-type-parameter": [
+    2,
+  ],
+  "@typescript-eslint/prefer-return-this-type": [
+    2,
+  ],
@@ -780,6 +850,12 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   "@typescript-eslint/unbound-method": [
     2,
   ],
+  "@typescript-eslint/unified-signatures": [
+    2,
+  ],
+  "@typescript-eslint/use-unknown-in-catch-callback-variable": [
+    2,
+  ],
@@ -1222,6 +1298,9 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   "no-reserved-keys": [
     0,
   ],
+  "no-return-await": [
+    0,
+  ],
@@ -1310,6 +1389,9 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   "no-useless-catch": [
     2,
   ],
+  "no-useless-constructor": [
+    0,
+  ],
@@ -7049,7 +7361,7 @@ exports[`validate config the legacy recommended config is correct 1`] = `
     "off",
   ],
   "constructor-super": [
-    "off",
+    2,
   ],
@@ -7112,7 +7424,7 @@ exports[`validate config the legacy recommended config is correct 1`] = `
     "off",
   ],
   "getter-return": [
-    "off",
+    2,
   ],
@@ -7591,7 +7903,7 @@ exports[`validate config the legacy recommended config is correct 1`] = `
     0,
   ],
   "no-const-assign": [
-    "off",
+    2,
   ],
@@ -7714,7 +8026,7 @@ exports[`validate config the legacy recommended config is correct 1`] = `
     "error",
   ],
   "no-redeclare": [
-    "off",
+    2,
   ],
@@ -7756,19 +8068,19 @@ exports[`validate config the legacy recommended config is correct 1`] = `
     "off",
   ],
   "no-undef": [
-    "off",
+    2,
   ],
@@ -7783,7 +8095,7 @@ exports[`validate config the legacy recommended config is correct 1`] = `
     "error",
   ],
   "no-unused-vars": [
-    "off",
+    2,
   ],
@@ -7804,7 +8116,7 @@ exports[`validate config the legacy recommended config is correct 1`] = `
     "off",
   ],
   "no-with": [
-    "off",
+    2,
   ],
@@ -9108,7 +9494,7 @@ exports[`validate config the legacy recommended config is correct 1`] = `
     "off",
   ],
   "unicorn/empty-brace-spaces": [
-    "error",
+    0,
   ],
@@ -9201,7 +9587,7 @@ exports[`validate config the legacy recommended config is correct 1`] = `
     "error",
   ],
   "unicorn/no-nested-ternary": [
-    "error",
+    0,
   ],
@@ -9270,7 +9656,7 @@ exports[`validate config the legacy recommended config is correct 1`] = `
     "error",
   ],
   "unicorn/number-literal-case": [
-    "error",
+    0,
   ],
@@ -9459,7 +9845,7 @@ exports[`validate config the legacy recommended config is correct 1`] = `
     "error",
   ],
   "unicorn/template-indent": [
-    "error",
+    0,
   ],
```

(Similar @typescript-eslint changes apply to index.mjs. Additional legacy rules changed from "off" to error: no-class-assign, no-dupe-args, no-dupe-class-members, no-dupe-keys, no-func-assign, no-import-assign, no-new-native-nonconstructor, no-obj-calls, no-setter-return, no-this-before-super, no-unreachable, no-unsafe-negation.)

## eslint-plugin-sonarjs v3 → v4

- `eslint-plugin-sonarjs` upgrade from v3 to v4 results in a corresponding major version change due to configuration changes. As codified in snapshots:

```diff
diff --git a/test/__snapshots__/test.spec.js.snap b/test/__snapshots__/test.spec.js.snap
index d404760..032574e 100644
--- a/test/__snapshots__/test.spec.js.snap
+++ b/test/__snapshots__/test.spec.js.snap
@@ -1702,9 +1702,6 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   "sonarjs/class-prototype": [
     0,
   ],
-  "sonarjs/code-eval": [
-    2,
-  ],
   "sonarjs/cognitive-complexity": [
     2,
     15,
@@ -1802,10 +1799,6 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   "sonarjs/encryption-secure-mode": [
     2,
   ],
-  "sonarjs/enforce-trailing-comma": [
-    0,
-    "always-multiline",
-  ],
   "sonarjs/existing-groups": [
     2,
   ],
@@ -2220,6 +2213,9 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   "sonarjs/no-selector-parameter": [
     2,
   ],
+  "sonarjs/no-session-cookies-on-static-assets": [
+    2,
+  ],
   "sonarjs/no-skipped-tests": [
     2,
   ],
@@ -2424,9 +2420,6 @@ exports[`validate config the flat config is correct for index.cjs 1`] = `
   "sonarjs/strings-comparison": [
     0,
   ],
-  "sonarjs/super-invocation": [
-    2,
-  ],
   "sonarjs/table-header": [
     2,
   ],
@@ -4785,9 +4778,6 @@ exports[`validate config the flat config is correct for index.mjs 1`] = `
   "sonarjs/class-prototype": [
     0,
   ],
-  "sonarjs/code-eval": [
-    2,
-  ],
   "sonarjs/cognitive-complexity": [
     2,
     15,
@@ -4885,10 +4875,6 @@ exports[`validate config the flat config is correct for index.mjs 1`] = `
   "sonarjs/encryption-secure-mode": [
     2,
   ],
-  "sonarjs/enforce-trailing-comma": [
-    0,
-    "always-multiline",
-  ],
   "sonarjs/existing-groups": [
     2,
   ],
@@ -5303,6 +5289,9 @@ exports[`validate config the flat config is correct for index.mjs 1`] = `
   "sonarjs/no-selector-parameter": [
     2,
   ],
+  "sonarjs/no-session-cookies-on-static-assets": [
+    2,
+  ],
   "sonarjs/no-skipped-tests": [
     2,
   ],
@@ -5507,9 +5496,6 @@ exports[`validate config the flat config is correct for index.mjs 1`] = `
   "sonarjs/strings-comparison": [
     0,
   ],
-  "sonarjs/super-invocation": [
-    2,
-  ],
   "sonarjs/table-header": [
     2,
   ],
@@ -8329,9 +8315,6 @@ exports[`validate config the legacy recommended config is correct 1`] = `
   "sonarjs/class-prototype": [
     "off",
   ],
-  "sonarjs/code-eval": [
-    "error",
-  ],
   "sonarjs/cognitive-complexity": [
     "error",
   ],
@@ -8416,9 +8399,6 @@ exports[`validate config the legacy recommended config is correct 1`] = `
   "sonarjs/encryption-secure-mode": [
     "error",
   ],
-  "sonarjs/enforce-trailing-comma": [
-    "off",
-  ],
   "sonarjs/existing-groups": [
     "error",
   ],
@@ -8782,6 +8762,9 @@ exports[`validate config the legacy recommended config is correct 1`] = `
   "sonarjs/no-selector-parameter": [
     "error",
   ],
+  "sonarjs/no-session-cookies-on-static-assets": [
+    "error",
+  ],
   "sonarjs/no-skipped-tests": [
     "error",
   ],
@@ -8983,9 +8966,6 @@ exports[`validate config the legacy recommended config is correct 1`] = `
   "sonarjs/strings-comparison": [
     "off",
   ],
-  "sonarjs/super-invocation": [
-    "error",
-  ],
   "sonarjs/table-header": [
     "error",
   ],
```
