Generate TypeScript definition files
It'd be very useful if neon could generate a TypeScript definition file (foo.d.ts) based on the functions (and possibly "interfaces") that are exported.
Since the parameters in TypeScript aren't actually parameters to the original Rust function, I'm experimenting with a #[jsfun()] attribute:
declare_types! {
pub class JsDbConn for DbConn {
#[jsfun()]
init(_cx) {
...
}
#[jsfun(): Array<Library>]
method getLibraries(mut cx) {
...
}
}
}
and a build.rs which extracts these and writes to an index.d.ts file.
In my own project I also define a couple of "types" which are essentially structs "exported" as interfaces in the definitions file.
Attributes have more defined syntax than I expected, so I'm now trying out doc comments instead, like this:
pub class JsDbConn for DbConn {
/// Connect to the database. Multiple connections can co-exist.
///
/// constructor()
init(_cx) {
...
}
/// Fetch all Libraries from the database.
///
/// getLibraries(): Array<Library>
method getLibraries(mut cx) {
...
}
}
This means we can also add documentation to the definition files, I think that'll look like this:
export class DbConn {
/*~ Connect to the database. Multiple connections can co-exist.
*/
constructor();
/*~ Fetch all Libraries from the database.
*/
getLibraries(): Array<Library>;
}
I'll post my code when I got everything working, but I think it might be better to rewrite it from the ground up for Neon as this is my first time parsing Rust code and I don't think I used syn properly.
Alright, I got it working for my project now. Here's what I got. I'll document it tomorrow as it's getting late here but I really think it's best to just rewrite proper code from scratch. But if anyone else wants this functionality right now, you should be able to just dump this in your build.rs and have it just work.
@darkwater Your link is 404, could you paste the code in a gist?
Wouldn't some cooperation with (or "inspiration by") https://github.com/rustwasm/wasm-bindgen be usefull since they also generate typescript defs & I'd suppose that it's in a pretty mature state.
@kubijo agreed! I just thought the same thing but you were faster 🚀
anyway, https://github.com/rustwasm/wasm-bindgen/tree/master/crates/backend seems to be a good start~
has there been any progress in this?
@Figments Not on this specifically—in time, the current class macro will probably be deprecated in favour of some other solution. At first, a lower-level primitive JsBox to safely pass Rust structs to JavaScript, and later possibly a proc macro like in node-bindgen. With a proc macro, we could definitely generate typings. I think it's hard to achieve in the current class macro. macro_rules! is not that powerful.
Anything I can do to help?
Anything new?
@TheBotlyNoob This would be a great feature, but unfortunately it's not something than anyone has been able to work on.
sad... thanks for the answer.
This is the main feature I was hoping for when considering a move from node-addon-api to neon. Is anyone working on this and looking for help?
@thegecko https://napi.rs/ has already supported this feature
Any updates here? Thanks!
I think this would be difficult at best or impossible at worst to implement because of the very dynamic nature of neon's API
Something like this would require proc macros and static function signatures. However, Neon has avoided these because of the amount of code they would need to inject.
However, GAT recently landed which could allow a trait based approach on tuple arguments to work. The prac macro could be limited to outputting the types and very light signature rewriting (zero code injection).
Something like:
#[neon]
fn greet(mut cx: FunctionContext, name: JsString, count: JsNumber) -> JsResult<JsString> {
todo!()
}
// transforms into
fn greet(mut cx: FunctionContext, (name, count): (Handle<JsString>, Handle<JsNumber>) -> JsResult<JsString> {
todo!()
}
This is a straightforward transform. No magic. However, this is only part of the puzzle. We have a function type definition, but we still need the type for the exports, modules, callbacks and a lot more.