For the sake of it, you could mimic the conciseness of a typedef by defining a minimal class with just variables in it (let’s call it TypeDefLike). It would extend an empty class (let’s call it TDL) which is marked with an @:autoBuild in order for all it’s subclasses (in our case TypeDefLike) to be run through a macro.
In the macro you get all variable fields defined in TypeDefLike and make them public. Then you generate a constructor field taking a parameter for each variable and storing the values in its own properties. Lastly you mark the class with @:rtti and @:structInit metadata.
This way you can create an instance of the class the same way you instantiate a typedef and can access its type information at runtime. The drawbacks are that
- you have some compile-time overhead (although negligible)
- the class definition isn’t as concise as a typedef
- you have some black magic going on in the code that’s not obvious
There’s a plus side too: you can provide default values for the variables, which you can’t do with a typedef.
Here’s an example Try Haxe !
It needs some modifications in order to compile as try.haxe.org disallows mentioning macro-related stuff.