Replies: 6 comments 1 reply
-
I wrote some code that seems to make it work a lot better. Below is a custom
And here is how I can use it. It seems to work and TypeScript helps out. So in the case of the signed in user I can access the
|
Beta Was this translation helpful? Give feedback.
-
I've tried writing a simpler helper component to do type narrowing but am having problems getting it to compile. It works fine when I use function syntax but if I call it using JSX syntax I get a TypeScript error. Very frustrating. Details in this discussion... I did some experimenting in React and it turns out they have the same problem. TypeScript can do proper type narrowing when called using regular JS, but for some reason type narrowing doesn't work when using JSX syntax. But in React you can use JS control flow to create different UI based on the shape of your data so this isn't an issue. I've been able to write components for Solid that help display discriminated unions using type narrowing BUT they only work (compile) when called using function syntax. So if I have a component called |
Beta Was this translation helpful? Give feedback.
-
Ok it seems like nobody cares about this due to lack of comments. But to me it seemed somewhat impossible or very cumbersome to display complex discriminated union, choice-type data structures, like what you'd get with
|
Beta Was this translation helpful? Give feedback.
-
Here is a more comprehensive example...
|
Beta Was this translation helpful? Give feedback.
-
For others discovering this only on GitHub: there is an associated discussion on SolidJS' Discord, here: https://discord.com/channels/722131463138705510/1074415945986080808/1074415948137758750 You will lose the performance benefits of SolidJS' In the Discord thread @jmagaram provides a type-aware narrowing pattern which also keeps the performance benefits of I think this is important stuff since this feels very hard to do nicely in SolidJS versus React. Ryan also weighed in on the Discord thread about upcoming changes in SolidJS 2 (semver major version 2) and why he couldn't make such a breaking change (which would accommodate this) right now as it would.. well be a breaking change for semver (SolidJS is currently on major version 1). |
Beta Was this translation helpful? Give feedback.
-
Sorry to necrobump (and someone may have come up with this in discord) but I found this discussion from a search, and ended up with the following utility, which might be helpful to someone else (you could clean it up if you want): const narrow = <A, B extends A>(accessor: Accessor<A>, guard: (v: A) => v is B): B | null => {
const val = accessor()
if (guard(val)) {
return val
}
return null
} and then when I use it as follows: // ...
<Show when={narrow(result, v => 'msg' in v)}>{success =>
<ShowSuccess success={success()} />
}</Show>
// ... the combo of using the show function, and having a conditional that returns the narrowed type or null seems to satisfy the type checker, since "msg" being a key in the result narrows it to a success type of the discriminated union. This probably has issues if the narrowed type includes null? Unsure. |
Beta Was this translation helpful? Give feedback.
-
I've gotten very excited about using SolidJS because of fewer abstractions, closer to DOM, Web component support, and performance. And so I tried building a basic web site this morning and very very quickly ran into a very awkward problem with TypeScript. I use discriminated unions all over the place like this below. Many of these union types have multiple options and sub-options especially if used to describe the UI state of a page. These kinds of data types are very common in functional programming.
It seems the only way to write a component that displays a
User
is to useShow
andSwitch
and then in the narrowed JSX scope I must cast each instance to something like(user() as AuthStatus_SignedIn_Admin).privileges
. If I'm using the narrowed value a lot, I can (must) write a wrapper component that takes a props with the typeAuthStatus_SignedIn_Admin
and then cast it once when passing it to that component. This is all a big hassle and ugly.In React I would just use the control flows built into javascript and get automatic type narrowing like this below. No need to manually define narrowed types or write separate helper components.
The documentation says there is an alternate version of
Show
but it has severe performance penalties.Is there a better solution to this problem I haven't considered? I'm wondering if using the Solid observables/rxjs would help. For DX I really think this should be addressed.
Here is a playground link
This seems related to #547
Beta Was this translation helpful? Give feedback.
All reactions