| > TypeScript will 'unwrap' the type anyway, unless you do funky stuff like this […] in which case things like `value += 1` will cause type errors because it coercies `value` from `Reactive<number>` to `number`. Yeah. I’ve spent more time than I’d like to admit trying to find a nice solution to this, and I’ve ultimately arrived at “it needs type system support to work for the general case”. I think you can make your brand (symbol) optional to address this case, but it doesn’t address this: > The type of `obj.message` is Reactive<string>, but it's _not_ reactive — it's a non-reactive snapshot of the value when the object was created. And here is the real problem: the types are right (in this case)! It’s Svelte that is wrong (in that it deviates from the JavaScript language semantics, which TypeScript has correctly modeled). This leads to my other ultimate conclusion with nominal primitive types: most of the time you’re better off just boxing the value… unless, or until, it becomes problematic for other reasons (eg performance, which would probably be a concern here, albeit one worth testing). Boxing allows correct, refined typing; it makes semantics of the value clear. The only downside is convenience… but this sort of convenience is exactly the kind of thing people rightly judge about the JS ecosystem. I’m not likely to use Svelte (for a variety of other reasons), so I don’t have a particular dog in this race… but I will say I find more explicit types for signals a great deal nicer to work with. Whether the explicit mechanism is a function call (like Solid) or an accessor (like many others). |