5

I'm trying to integrate Carbon Design System - React SDK in a Fable/Elmish application and it looks like I have to create the property type definitions (some of them I just guessed) for every component in order to use it.

The component already has TypeScript definitions in.


Do I really have to manually create type definitions for every React component I want to try or use?

Is there a simple or automatic way to use a React component from F# code without having to write the property type definitions for every component I want to try?

How do people in the F# community use the components from the React ecosystem?


I've tried ts2fable but it generates invalid unreliable code: Example where most lines have error, I've also transpiled dependencies (typings/shared.d.ts and React type definitions)

I'm also looking at TypeProviders but not sure if this can be a solution to my problem.

JamesFaix
  • 8,050
  • 9
  • 37
  • 73
A. Matías Quezada
  • 1,886
  • 17
  • 34

1 Answers1

2

Do I really have to manually create type definitions for every React component I want to try or use?

You do not have to create type definitions. Instead, you can write F# code that is not type-safe using the dynamic module provided by Fable.

Is there a simple or automatic way to use a React component from F# code without having to write the property type definitions for every component I want to try?

Currently there is the (imperfect) ts2fable tool, or you can write untyped F# code, taking care that the output will have the correct "shape" in JavaScript.

How do people in the F# community use the components from the React ecosystem?

Some common libraries have F# bindings that are available on Nuget. Otherwise you will need to write some bindings yourself, perhaps using ts2fable.

This is definitely a pain-point with Fable at the moment.


For example, say the JavaScript library expects a props object like this:

{
  foo: 1,
  bar: [ "a", "b", "c" ],
  qux: "hello"
}

Then we can create this in Fable like so:

open Fable
open Fable.Core
open Fable.Core.JsInterop

let props = 
  createObj [
    "foo" ==> 1
    "bar" ==> ResizeArray<_>([ "a"; "b"; "c" ])
    "qux" ==> "hello"
  ]

Compiles to...

export const props = {
    foo: 1,
    bar: ["a", "b", "c"],
    qux: "hello",
};

The F# type of props is obj.

The ==> operator is just for convenience. You could also write:

open Fable
open Fable.Core
open Fable.Core.JsInterop

let props = 
  createObj [
    "foo", box 1
    "bar", box (ResizeArray<_>([ "a"; "b"; "c" ]))
    "qux", box "hello"
  ]

This is great for trying things out. However, you will be missing out on some the strongly-typed benefits of F#! Whether or not this trade-off is worth it will depend on your use-case.


In theory, a Type Provider could be written that takes an NPM module name and returns an appropriate F# type, perhaps leveraging ts2fable. This would be very powerful, but I don't think anyone has implemented this yet.

sdgfsdh
  • 33,689
  • 26
  • 132
  • 245