feat: State declarations in class constructors#15820
There's an annoying problem right now, which comes in about two flavors: ```ts class Counter { count = $state<number>(); constructor(init: number) { // oops, forgot to assign init to count, but TypeScript // can't help because it thinks it's been assigned above! } } ``` In this case, TypeScript can't help out because it thinks `count` has been assigned at its declaration, when it has not! The other version is: ```ts class PluggableCounter { count = $state(0); plugin = $state(); // I shouldn't have to do this custom = $derived(this.plugin(this.count)); constructor(plugin: (c: number) => number) { this.plugin = plugin; } } ``` There are other examples and edge cases (`$derived` class fields don't play well if you need to reference a non-stateful class field, for example), but the whole class of problem essentially boils down to "sometimes you need to be able to create state in the constructor". After this PR, you can: ```ts class PluggableCounter { count = $state(0); custom: number; constructor(plugin: (c: number) => number) { this.custom = $derived(plugin(this.count)); } } ``` There's a really simple set of rules to follow to declare state in the constructor: - The field must not already be declared state - In the constructor, the _first assignment_ to the field must be with the rune - Creation of the state field can only occur at the top level of the constructor (i.e. not in callbacks or control flow blocks) ### Before submitting the PR, please make sure you do the following - [ ] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs - [ ] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`. - [ ] This message body should clearly illustrate what problems it solves. - [ ] Ideally, include a test that fails without this PR but passes with it. - [ ] If this PR changes code within `packages/svelte/src`, add a changeset (`npx changeset`). ### Tests and linting - [ ] Run the tests with `pnpm test` and lint the project with `pnpm lint`
This issue appears to be discussing a feature request or bug report related to the repository. Based on the content, it seems to be still under discussion. The issue was opened by elliott-with-the-longest-name-on-github and has received 3 comments.