Using typescript compiler api to help generating bindings

The typescript compiler has an API. It could be useful in the often tedious task of writing / generating purescript bindings. I tried it a little bit. It is definitely capable but the API is a huge beast in itself and the documentation is sparse.

Would appreciate any pointers about the API. If not 100% automatically generating bindings for purescript, a tool that can query the full type of any given javascript / typescript symbol in node_modules will save a lot of time.

I checked out this TS compiler API some time ago to evaluate if a tool like this is possible. Unfortunately I don’t have the code snippets anymore. I think the outcome was that even though the API is a bit tough it should be possible. But I think there are many questions to be answered apart from this. Should the tool support all TS types or just a subset? Which PureScript types should be generated for the less trivial TS types? At that time I decided for myself that instead of aiming to have two tools (“TS to PureScript” and “PureScript to TS”) it would be better to have a stable way to generate from PureScript to TS first. Since this can be indirectly used for the purpose of FFI (see my recent posts here about this topic).

1 Like

Thanks a ton, this can not be more timely. It seems the VariantEncodedFlat, OneOf and TsRecord you mentioned in the other post have already covered a lot ground.

My initial thought was more on the TS → Purescript side of the thing. I have been working on a binding for three.js. In there almost everything is a Object3D, so for a type of my choice I want to ask:

  • what types are on the inheritance chain leading to Object3D
  • for every public, i.e. exported type on that chain, what properties it has taking into account TS utilities such as Omit.
  • from there, a series of purescript row types can then been generated.

It is like a automated fancier LSP go-to-definition. But the binding helpers you mentioned are available and I’m pretty sure it will be helpful in this project of mine.

Thanks again.

Hi,

First of all there is an open organization which we formed long time ago around the code-gen topic: purescript-codegen · GitHub (it was formed before tidy-codegen etc.).

There are two projects in that org which I’m still hacking on from time to time and they are closely related to the TS->PS code generation.

  1. purescript-js-object (a cheap and type safe binding layer to mutable JS/TS objects, classes and modules).
    js-object has some documentation in the README. It provides helpers and codegen (!) for JS object bindings. I added few more things in the meantime which are not documented in the README - stub for JS classes and instances binding.
    The purpose of this lib is to minimize JS which you have to write or generate when bind to TS/JS: library repo.

  2. There is also a purescript-read-dts library which lacks documentation and focuses on the typescript compiler API and possible codegen out of that (exactly what you suggested @edwardw). It should be renamed and split into multiple packages at the end:

  • Here’s a subpackage that provides bindings to the TypeScript compiler: TypeScript compiler bindings.
  • Some extras like: helpers for testing.
  • And here’s a subpackage that builds an opinionated AST from TypeScript types: AST builder from TypeScript types.
  • The project contains also pretty systematic test suite. I even started to play around with three.js types transformations: test suite.
  • The missing part is the codegen itself. The codegen(s!) should be a flexible set of possible strategies that could be manually tweaked.
  • Using a previous version of this library we were able to do a codegen for this library: react-basic-mui. I decided to rewrite read-dts with a more systematic approach (proper bindings to the compiler API, etc.).

Guys, if you’re really interested in this topic, I’m happy to share more about what’s really in the project, and maybe even form a working group around it.

2 Likes

Exactly this. Still reading through all the links you posted paluh. In the meantime, I could already see that purescript-js-object is going to ease one major pain of the three.js binding, which is a lot of getter/setter. And I wish I’ve found purescript-read-dts sooner. With it, a codegne in the same vein of react-basic-dom is suddenly possible.

Tried js-object in my project: PR. I especially like the share of function signature, so that Vector2, Vector3, Vector4 etc. can have the same x function. No need to prefixing or post-fixing it with object name to preempt name clash.

Sorry for late response.

Tried js-object in my project: PR 1

That is really cool that you found this useful especially in such ac cool project as react-three-fiber binding - I would love to try it out!

And I wish I’ve found purescript-read-dts sooner.

So the problem with this lib is actually codegen plus some ecosystem where you can find existing patterns of some codegen (like react related etc.) to copy and reuse. The initial effort can be still pretty demanding :frowning: