ocsigen / ts2ocaml

Generate OCaml bindings from TypeScript definitions via the TypeScript compiler API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support references

tmattio opened this issue · comments

/// <reference lib="es5" />

in TypeScript files should translate to

include module type of struct include Es5 end
  • On generating the standard libraries, /// <reference lib="..." /> is useless in ts2ocaml because we bundle TypeScript standard libraries as a single Ts2ocaml module, so users would just have to do open Ts2ocaml.
    • I added language version: ... comments to the types and functions which are only available in a specific language version:
module[@js.scope "Array"] Array : sig
  ...

  (**
    Calls a defined callback function on each element of an array, and returns an array that contains the results.
    @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
    @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
  *)
  val map: 'T t -> callbackfn:(value:'T -> index:float -> array:'T list -> 'U) -> ?thisArg:any -> unit -> 'U list [@@js.call "map"]

  ...

  (**
    language version: ES2019
    Calls a defined callback function on each element of an array. Then, flattens the result into
    a new array.
    This is identical to a map followed by flat with depth 1.
    @param callback A function that accepts up to three arguments. The flatMap method calls the
    callback function one time for each element in the array.
    @param thisArg An object to which the this keyword can refer in the callback function. If
    thisArg is omitted, undefined is used as the this value.
  *)
  val flatMap: 'T t -> callback:(this:'This -> value:'T -> index:float -> array:'T list -> ('U, 'U ReadonlyArray.t) union2) -> ?thisArg:'This -> unit -> 'U list [@@js.call "flatMap"]

  ...
end
  • On generating wrappers for npm packages, we can't rely on <reference lib="..." /> because adding it is only recommended but not required.
    • Most TS library authors use tsconfig.json to specify which lib they are using.
    • As described above, we now have one big module Ts2ocaml which contains everything, so users would just have to do open Ts2ocaml.

On the otherhand, <reference path="..." /> and <reference types="..." /> are worth checking out.

  • I'm wondering if we should respect <reference path="..." /> and load the referenced file to bundle together.
  • I think we can just generate open statements for <reference types="..." />.

With ts2ocaml 1.0.0 I get empty file when trying to generate Node.js bindings, which are notoriously complex. Index file contains only references to other files, which mostly contain ambient modules... Is the goal for ts2ocaml to be able to get through all that, or Node bindings are cheaper to hand craft and deploy as another stdlib shim?

@Lupus This is difficult because of the reason similar to relative imports. See #16 (comment) .

@Lupus Also, I admit the binding to Node.js base library is too complex to generate automatically, and so should be hand-crafted. ts2ocaml will still save a lot of boilerplates, though.

I think it's more of community building problem, if each author of bindings would reach a dependency on Node.js at some point, and will have to hand-craft partial bindings for required Node.js API surface themself - resulting in multiple disjoint and incompatible sets of bindings.

I will try to feed @types/node to ts2ocaml and see what happens. I'm working on #35 so I might be able to further improve it by looking at the results.

@types/node is a good test case for the generator. I managed to get pretty far with "traverse module exports with TypeChecker API" approach (see here for general idea), an improved version of that gist produced copileable (and working!) bindings for cassandra-driver and @types/ldapjs, but failed to produce compileable output for @types/node, mostly because of weird global modules like Buffer and NodeJS, they were not really exported anywhere and I had hard time building type paths for symbols which end up in those modules...

Since b02aff2 and #37, ts2ocaml now emits appropriate open statements for <reference path="..." /> and <reference types="..." />. I think I can close this.