typescriptsveltesvelte-5

Svelte 5 - using $state for class field in TypeScript


I have a class:

class TestClass {
    prop = $state('test');
}

It works in .svelte.js and .svelte files with <script lang="js">, but doesn't work in .svelte.ts and .svelte files with <script lang="ts">. Getting this error:

CompileError: $state(...) can only be used as a variable declaration initializer or a class field

Am I doing anything wrong or Svelte 5 just doesn't support TS class field states yet?

My tsconfig.json file content:

{
  "extends": "./.svelte-kit/tsconfig.json",
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "module": "es2020",
    "lib": ["es2020", "dom"],
    "target": "es2019",
    "importsNotUsedAsValues": "error",
    "isolatedModules": true,
    "resolveJsonModule": true,
    "sourceMap": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "baseUrl": ".",
    "allowJs": true,
    "checkJs": true,
    "paths": {
      ....
    }
  },
  "include": [
    ....
  ],
  "exclude": ["node_modules/*"]
}

Solution

  • You may have a TS configuration that specifies a target (or uses the default) which causes the class to be compiled down to a function for compatibility with < ES6 or the class field initializers may be turned into constructor assignments, which is not allowed prior to Svelte 5.31.0.

    Hence you have to make sure the target is at least "es6" or "es2015" and if the target is lower than "es2022" then useDefineForClassFields has to be set to true for older Svelte 5 versions (see documentation and notes on default value).