Experimental Features
Beware, all ye who tread here.
Please use these features cautiously. Some computation expressions are more tested than others in real world usage.
Computation Expressions
Many methods in Solid-js
use lambdas without parameters as arguments to maintain reactivity such as createEffect
.
For these, computation expressions are provided that abstract away the method call and empty function boiler plate. However, if you want to use the options or overloads available to one of the methods, then you'll need to call it directly instead of using a CE sugar.
To access these expressions, you must open the Partas.Solid.Experimental
namespace.
lambda
Wraps the computation in fun () -> ...
let config = lambda { Data.config.data }// Same aslet config = fun () -> Data.config.data
console.log (config())
effect
Wraps the computation in createEffect(fun () -> ...)
effect { console.log "I'm in an effect"}// Same ascreateEffect(fun () -> console.log "I'm in an effect")
mount
Wraps the computation in onMount(fun () -> ...)
mount { Data.Config.resource.refetch()}// Same asonMount(fun () -> Data.Config.resource.refetch())
cleanup
Wraps the computation in onCleanup(fun () -> ...)
cleanup { thishere.available <- false}// Same asonCleanup(fun () -> thishere.available <- false)
memo
Wraps the computation in createMemo(fun() -> ...)
memo { // ...}// Same ascreateMemo(fun () -> ...)
batch
Wraps the computation in batch(fun () -> ...)
let submissionResult = batch { // Some reactive tasks here}// Same aslet submissionResult = batch(fun () -> // Some reactive tasks here)
lazyload
Wraps the computation in lazy'(fun () -> ...)
let comp = lazyload { importComponent "./MyComponent.fs.jsx" }// Same aslet comp = lazy'(fun () -> importComponent "./MyComponent.fs.jsx")
selector
Wraps the computation in createSelect(fun () -> ...)
let isSelected = selector { // ...}// Same aslet isSelected = createSelect(fun () -> // ...)
children
Wraps the computation in children(fun () -> ...)
let childs = children { props.children}// Same aslet childs = children(fun () -> props.children)
Erased Union Implicit Casting
When making bindings, it is common to have a function accept multiple different value types. Ordinarily, you would have to use the additional !^
operator to cast into these
bindings erased unions.
Within the Experimental namespace, you can open the U
module, which reimplements the erased unions of fable with implicit casting into the union.
I find this most useful when creating bindings, because it's less noisy when using them.
Make sure your access to Partas.Solid.Experimental.U
comes AFTER Fable.Core
.
open Fable.Coreopen Fable.Core.JsInteropopen Partas.Solid.Experimental.U
[<Import("somefunction","somelibrary")>]let numberOrString (value: U2<string, int>): obj = jsNative
// previously you would have:numberOrString !^"Something"numberOrString "Something" // Will cause an errornumberOrString !^3. // Will cause an error// With the experimental casting you can do:numberOrString "Something"numberOrString 2numberOrString 3. // Will cause an error// Depending on your configuration, you may get compiler warnings for op_Implicit usage. This can// then be resolved by explicitly using !^, but at least you won't be obstructed from using the function as expected
These implicit helpers do not work with arrays/lists without either explicitly typing the value as an accepted array/list type or
by using the erase operator !^
. In other words, the behaviour returns to normal for these cases, requiring explicit casting with !^.
let numberOrString (value: U2<int, int list>): obj = jsNative
numberOrString 5 // worksnumberOrString [ 5; 6 ] // Error: Expected type U2<int, int list>, but got 'a listnumberOrString ([5;6] : int list) // worksnumberOrString !^[ 5; 6 ] // worksnumberOrString !^[ "5"; "6" ] // error as expected
Last updated: 7/9/25, 7:54 PM