Closed fullofcaffeine closed 5 years ago
I've just merged a PR I had waiting for a while - can you try with master
branch? And otherwise please isolate the generation issue in an example (could be a gist)
Hi Philippe, thanks a lot for the reply!
Nice to know there are other people interested in this project, I thought it was dead :)
I pulled your changes for hxtsdgen
and tried compiling again. Now it errors but at least it shows what it would generate otherwise (before it'd just generate the wrong type), which seems to be now the correct type with the correct type parameter:tink.core.Outcome<Result, tink.Error>
. The error says:
Uncaught exception Cannot render type tink.core.Outcome<Result, tink.Error> into a TypeScript declaration (TODO?)
The full stacktrace:
pwa-ts-haxe-boilerplate-take-2 (master●)$ haxe build-client.hxml [2.5.0]
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/TypeRenderer.hx:83: characters 17-22 : Uncaught exception Cannot render type tink.core.Outcome<Result, tink.Error> into a TypeScript declaration (TODO?)
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/TypeRenderer.hx:70: characters 25-95 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/TypeRenderer.hx:29: characters 79-97 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/TypeRenderer.hx:29: characters 49-98 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/TypeRenderer.hx:51: characters 25-95 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/TypeRenderer.hx:70: characters 25-95 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/TypeRenderer.hx:70: characters 25-95 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/TypeRenderer.hx:51: characters 25-95 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/TypeRenderer.hx:70: characters 25-95 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/Generator.hx:129: characters 75-96 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/Generator.hx:185: characters 44-111 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/Generator.hx:206: characters 21-42 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/Generator.hx:98: characters 60-73 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/Generator.hx:143: lines 143-212 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/Generator.hx:75: characters 39-67 : Called from here
/home/fullofcaffeine/haxe/haxe_libraries/hxtsdgen/0.0.1/github/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/Generator.hx:54: characters 40-61 : Called from here
And otherwise please isolate the generation issue in an example (could be a gist)
This project isolates the issue. The relevant files are:
You can reproduce by installing the required libs (I use Lix: lix download
, I'm using Haxe 4.0.0-rc.2+92c7833
) and then trying to compile with the build-client.hxml
, and you'll get the error/stacktrace I've shown above.
@fullofcaffeine seems like enums are not supported in the output (yet): https://github.com/nadako/hxtsdgen/blob/8244c170445c7f763045f2eca18a1b77beab8688/src/hxtsdgen/TypeRenderer.hx#L82-L83 Newer haxe versions define enums as objects in js (http://try-haxe.mrcdk.com/#35864).
enum MyEnum {
A;
B(a: Int, b: String);
}
Compiles values to a structure like this:
{
_hx_index: 0,
__enum__: "MyEnum"
}
{
_hx_index: 1,
a: a,
b: b,
__enum__: "MyEnum"
}
To use that in ts (and have some type safety) you'd have to generate a number of typings:
enum MyEnumIndex { // Or some other name
A = 0,
B = 1
}
type MyEnumValue = // Again random name here
| {_hx_index: MyEnumIndex.A}
| {_hx_index: MyEnumIndex.B, a: number, b: string}
type MyEnum = {
A: {_hx_index: MyEnumIndex.A}
B(a: number, b: string): {_hx_index: MyEnumIndex.B, a: number, b: string}
}
To render it somewhat useable on the ts side:
const myenumvalue = MyEnum.B(1, 'one')
switch (myenumvalue._hx_index) {
case MyEnumIndex.A: console.log('A'); break
case MyEnumIndex.B: console.log(myenumvalue.a, myenumvalue.b)
}
Ah, indeed! Thanks for elaborating!
Even though it'd be great to support the typing and emulate enums at the TS side, one possible workaround to avoid this kind of complexity now is to just handle all enums at the Haxe side. I'll try it out with the new patch from @elsassph and report my findings here.
FYI There are plans to rename that field to $index
, see https://github.com/HaxeFoundation/haxe/issues/7165. In general one should not rely on enum internal structure tho...
So, I changed the sample code to handle the Outcome at the Haxe level, see: https://github.com/haxe-boilerplate/pwa-ts-haxe-boilerplate-take-2/blob/master/src/hx/client/TinkProxy.hx#L17, but now I'm getting a StackOverflow
error when compiling. Seems related to https://github.com/nadako/hxtsdgen/issues/5.
To reproduce, just try compiling with the build-client.hxml
hxml file. It will hang for a while and then fail with the aforementioned error.
FYI There are plans to rename that field to $index, see HaxeFoundation/haxe#7165. In general one should not rely on enum internal structure tho...
Opening a parenthesis here, but I have to ask - what is that field about? Is it documented somewhere?
It's not documented, because it's an implementation detail, but it's the enum constructor index, obviously :-P
@nadako Got it :)
Some good points here: when I use this tool, for what is a public API, I use an #if
define to replace some typedefs with interfaces, and of course only use statics instead of enums.
But maybe @benmerckx 's suggestion for enums could be usable, but enums internal representation seems to be a loving target: it was an Array, and now is replaced by an object (as Ben described).
Some good points here: when I use this tool, for what is a public API, I use an
#if
define to replace some typedefs with interfaces, and of course only use statics instead of enums.
Interesting. Do you have a gist of this approach somewhere?
and of course only use statics instead of enums.
What do you mean? Could you exemplify?
New features since a few PRs were merged:
However, for this specific issue, types are still NOT "transitively" emitted; that is if a function returns or expects a certain type, hxtsdgen won't automatically export the referenced type. You must annotate everything explicitly for now.
Tink json and json2object can serialize enum i think
@francescoagati serialization is a different topic unfortunately. Haxe compiler doesn't do anything with @:expose
and enums: they aren't exposed to the JS world.
Hi @nadako,
First of all, thanks for taking the time to develop and share
hxtsdgen
!I've been experimenting with it lately*[0]. I added it as an extension of
hxgenjs
and have been playing with it standalone (the default use-case described in its README). For the most part it works great, but I've found one show-stopper (for me) issues so far. I'm not sure if it has to do with the type being complex or it being a third-party haxelib or if that's because the actual type is generated by a macro (at least I think the issue is about, but I'm not 100% sure).Here's an example:
1) https://github.com/haxe-boilerplate/pwa-ts-haxe-boilerplate-take-2/blob/master/src/hx/client/TinkProxy.hx, this class uses
tink_web
'sProxy
functionality and returns the call toremote.json()
. This should return a typed tinkFuture
. 2)hxtsdgen
generates it astink.core._Future.FutureObject
, but it renders thed.ts
invalid: there's no reference totink.core._Future.FutureObject
anywhere, so it errors with acannot find namespace "tink"
error message intsc
. See: https://github.com/haxe-boilerplate/pwa-ts-haxe-boilerplate-take-2/blob/master/src/ts/client/hx.d.ts#L18. I had to comment the generated line out and add another one withany
as the return type to maketsc
happy about it.I was instead expecting
hxtsdgen
to generate a ts type definition for a typed tinkFuture
(likeFuture<Resut>
, whereResult
is https://github.com/haxe-boilerplate/pwa-ts-haxe-boilerplate-take-2/blob/master/src/hx/client/TinkProxy.hx#L23 and defined https://github.com/haxe-boilerplate/pwa-ts-haxe-boilerplate-take-2/blob/master/src/hx/ApiResult.hx.Is that to be expected or is that a scenario that's not currently handled by
hxtsdgen
? I'm a bit lost here so any insights would be appreciated!*[0] Here and here. Both experiments use
hxtsdgen
. The first one combines it withhxgenjs
.