ocsigen / ts2ocaml

Generate OCaml bindings from TypeScript definitions via the TypeScript compiler API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`?` properties are not marked as potentially `undefined`

zbaylin opened this issue · comments

If I have an interface that looks like

interface Foo {
  bar? : string  
}

All of these definitions satisfy Foo:

const x : Foo = { bar: "hello world" }
const y : Foo = { bar : undefined }
const z : Foo = { }

However, the OCaml generated by ts2ocaml assumes bar is always present as a string:

...
module Foo : sig
  type t = _Foo
  ...
  val get_bar: t -> string [@@js.get "bar"]
  val set_bar: t -> string -> unit [@@js.set "bar"]
  ...
end

Whereas if I modify Foo to be

interface Foo {
  bar: string | undefined
}

the tool recognizes that bar is "undefinable":

...
module Foo : sig
  type t = _Foo
  ...
  val get_bar: t -> string option [@@js.get "bar"]
  val set_bar: t -> ([`Undefined of undefined | `U1 of string] [@js.union]) -> unit [@@js.set "bar"]
  ...
end

@smorimoto I believe this is just a bug and not a lack of a feature; I think I have implemented it before but somehow broke it later.

I'll make a new release and it will be live within about an hour. Note that it will now emit something like this:

module Foo : sig
  type t = _Foo
  ...
  val get_bar: t -> string option [@@js.get "bar"]
  val set_bar: t -> string -> unit [@@js.set "bar"]
  ...
end

since setting undefined is a different thing than removing a field (exactOptionalPropertyTypes in TypeScript).

However, as @smorimoto said, it makes sense to have an option to configure this behavior. Please open another issue if you want it 🙂