Skip to content

[Help Wanted/Design] Improve TypeScript integration #1887

@matthid

Description

@matthid

What?

Basically, I want to improve the interop with TypeScript and asking for help and directions.

This means extending the fable-compiler in two areas:

  1. Emit TypeScript bindings (we currently write them by hand)
  2. Consume/Import TypeScript (we currently use ts2fable for this)

Please feel free to correct me throughout the post, suggest alternative implementations or even point out why this is a bad idea. Any help regarding the design, implementation or else is welcome. Feel free to connect privately via Twitter or Slack (or Mail).

Why?

The linked related issues (see the end of this post) should give a couple of reasonable use cases. But in particular:

  • After "1." it is easier to publish fable-based libraries on npm without any additional manual work.
  • "1." should allow import "./MyFile.fs" in TypeScript/Javascript with proper IDE support. (It is not exactly clear what additional thing we would need to do here for the IDE to pick up the typings)
  • "2." Would make it a lot easier for newcomers to use packages in the npm ecosystem
  • "2." Might allow us to reduce our work of maintaining and keeping the typings updated.
  • (Future discussions, just thinking our loud) After 1 + 2 we could potentially publish packages on npm. For F# tooling we might still need to include a reference assembly (or just the .net assembly, considering WebAssembly...). There are however a lot of other issues to be solved. Just putting this here to put it up for discussion if this is what we want eventually.

How?

I'd like to talk about 1 only for now (and extend the post later)

Emit TypeScript bindings

Looking at the available APIs and the related discussions I feel like the best bet is to use the TypeScript API as there are online tools which make is easy to understand and work with.

I have played a bit with the code base and noticed the following:

  • We could just use the TypeScript-API in fable-compiler-js, we just need a couple of bindings or use unsafe calls.
  • However, in regular .NET based fable we cannot use the TypeScript API, so we need a intermediate serializable datastructure for type declarations built from Fable.AST. It will look similar to Fable.AST but only type-specific stuff (all Expression stuff will be removed)
  • I haven't figured out what the best way is to inject TypeScript definitions into webpack via fable-loader, but as a first step I would just output the .d.ts files somewhere (alongside the .fs file for example).

Yes it probably is a bit of work but all it all it sounds doable to me. In practice:

  • We could start with a quite minimal implementation only supporting simple interfaces (for example) and using any for everything else
  • We probably want to make this opt-in until we are more confident
  • We can extend this feature for feature (ie typings will become better over time)

Consume/Import TypeScript

I will expand this section later or throughout this discussion. But my current ideas are:

  • Create a "build-in" type-provider type MyTypings = TscImport("typings.d.ts")
  • Write .fs files, for example based on attributes -> add to project file via globbing

Related issues

This issue is a continuation of:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions