sveltejs / svelte

Cybernetically enhanced web apps
https://svelte.dev
MIT License
77.15k stars 4.02k forks source link

Critial: static analyze some.svelte.ts #11605

Open Black1358 opened 1 month ago

Black1358 commented 1 month ago

Describe the bug

This code throw Error when file named with .ts extention:

class ReactiveRecord {
    store = $state(null);

}

export const create = () => {
    return new ReactiveRecord();
}

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

If the file is named .js, everything is working correctly.

Reproduction

I've been researching the internal files and this is what I found:

svelte\src\compiler\phases\2-analyze:

function validate_call_expression(node, scope, path) {
//...
    if (
        rune === '$state' ||
        rune === '$state.frozen' ||
        rune === '$derived' ||
        rune === '$derived.by'
    ) {
        if (parent.type === 'VariableDeclarator') return;
        if (parent.type === 'PropertyDefinition' && !parent.static && !parent.computed) return;
        console.log("parent", parent);
        e.state_invalid_placement(node, rune);
    }
//...
}

Logs

"parent": Node {
  type: 'AssignmentExpression',
  operator: '=',
  left: Node {
    type: 'MemberExpression',
    object: Node {
      type: 'ThisExpression',
    },
    property: Node {
      type: 'Identifier',
      name: 'store'
    },
    computed: false,
    optional: false
  },
  right: Node {
    type: 'CallExpression',
    callee: Node {
      name: '$state'
    },
    arguments: [ [Node] ],
    optional: false
  }
}

System Info

Node: 20.11.1
svelte: 5.0.0-next.132
ts: 5.4.5
tsconfig: auto, included in create@svelte without custom editions

import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
Calling the Error for use with and without this preprocessor

Severity

annoyance

dummdidumm commented 1 month ago

Please provide a reproduction (via sveltelab.dev or stackblitz or Github repo) so we can look into why the .svelte.ts file wasn't analyzed.

Black1358 commented 1 month ago

https://github.com/Black1358/svelte-error-ts

I created a repository and found what is the trigger of my problem. For WebStorm, I changed the target in the compilerOptions (tsconfig). The ES2020 target is incompatible and throws an error in this case.

p.s. With ES2022 all works correctly

brunnerh commented 1 month ago

This is a documentation issue for TS usage. I outlined the requirements before over here.

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.

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 (see documentation and notes on default value).

If constructor assignments are allowed (#11455), just the transpilation of classes would need to be prevented.