Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

svelte 5: typescript decorations not compatible with tsconfig.json required for runes to work in classes #11339

Open
petermakeswebsites opened this issue Apr 25, 2024 · 1 comment · May be fixed by #11455

Comments

@petermakeswebsites
Copy link

petermakeswebsites commented Apr 25, 2024

Describe the bug

Note: This bug report has nothing to do with using runes in conjunction with decorations, but rather using decorations at all anywhere in the entire codebase.

This is a fairly low priority bug, if it could even be considered a bug, but given that decorations will become more popular pretty soon as they are gradually integrated into browsers, it may be worth giving some forethought. It's also possible that this is purely a typescript problem and nothing really Svelte can or should do about it.

Decorations require the experimentalDecorators in tsconfig.json. However, useDefineForClassFields needs to be set to false in tsconfig.json in order for them to work.

On the other hand, in order for runes to work in any file, useDefineForClassFields needs to be set to true - which is the default.

This creates a situation where either A) no runes work or B) no decorators work (at least field property decorators). This has nothing to do with them being used in the same class or file. It's codebase-wide.

Reproduction

Reproduction requires fiddling with tsconfig.json so reproduction in REPL is not possible AFAIK. Fortunately it's simple to do. Just import the following my-class.ts and state.svelte.ts into the app.

"Default mode"

   ...
   "experimentalDecorators": true,
   "useDefineForClassFields": true // default
   ...

my-class.ts

function Log(target: any, propertyKey: string) {
    console.log(`Field "${propertyKey}" has been decorated`);
}

class MyClass {
    @Log // ignored - no error
    myField: number;
}

state.svelte.ts

class SomeClass {
    state = $state("hello") // works fine
}

"Decorator mode"

   ...
   "experimentalDecorators": true,
   "useDefineForClassFields": false // <---
   ...

my-class.ts

function Log(target: any, propertyKey: string) {
    console.log(`Field "${propertyKey}" has been decorated`);
}

class MyClass {
    @Log // Field myField has been decorated - works
    myField: number;
}

state.svelte.ts

class SomeClass {
    state = $state("hello") // `$state(...)` can only be used as a variable declaration initializer or a class field 
}

Logs

Here is the piped typescript output from the compilation with useDefineForClassFields set to false. You can see typescript decides to put the initialisers in the constructor, which breaks $state.

class SomeClass {
  constructor() {
    this.state = $state("hello");
  }
  // 
}
export const MyClass = new SomeClass();

System Info

svelte: 5.0.0-next.115
typescript: ^5.4.5

Severity

annoyance

@fcrozatier
Copy link
Contributor

Decorations require the experimentalDecorators in tsconfig.json

That is not the case anymore in typescript 5+ for Stage 3 decorators. Here's what the announcement says:

--experimentalDecorators will continue to exist for the foreseeable future; however, without the flag, decorators will now be valid syntax for all new code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants