typescripten: Type-safe JavaScript interop with complex types

90 views
Skip to first unread message

Sebastian Theophil

unread,
Dec 28, 2021, 5:21:24 AM12/28/21
to emscripte...@googlegroups.com
Hi,

I wanted to plug my own project for some time here on the mailing list because it also handles JavaScript - C++ interop and now wajic came up so I thought I pitch in. 

My project https://github.com/think-cell/typescripten produces type-safe C++ interfaces to JavaScript standard libraries or third-party libraries. It reads TypeScript interface definition files and transforms them into C++ shims based on emscripten. 

The resulting C++ code is often a straight-forward port from TypeScript/JavaScript, e.g., 

JavaScript:

var elem = document.createElement("p")
elem.innerText = "Hello CppCon 2021"
elem.style.fontSize = "20.0"
document.body.appendChild(elem)

C++:

auto elem = js::document()->createElement(js::string("p"));
elem->innerText(js::string("Hello CppCon 2021"));
elem->style()->fontSize(js::string("20vh"));
js::document()->body()->appendChild(elem);

No macros and the C++ functions return typed JavaScript objects! Because we use the TypeScript interface definitions, the C++ code is typechecked. Passing a number to fontSize will create a compiler error. 

The project is not yet meaningfully complete but it bootstraps successfully, i.e., the compiler understands the interface definition file for the TypeScript compiler and parser API that it uses itself. TypeScript generic constraints are not yet supported, for example, but should be. 

Maybe somebody else finds this useful. We have used it internally for a small web app already that needed to call the tableau.com JavaScript API. 

Regards
Sebastian 

Alon Zakai

unread,
Jan 6, 2022, 3:59:12 PM1/6/22
to emscripte...@googlegroups.com
Hi Sebastian,

This is really nice! I watched your talk as well at CppCon (https://www.youtube.com/watch?v=CLuhogat6aY), very interesting.

For a while it's seemed like we need something in this general area, so it's great to see it happen! I think this is a very good design, too (the performance issue with strings is the one concern I have, but as you say in the talk, that can be optimized - I'd use EM_JS for that probably).

Did you have ideas about integrating this with upstream Emscripten? I think that might make sense to do, although maybe as part of a larger conversation on our bindings story (atm we have embind and the WebIDL binder, which already have some overlap).

- Alon Zakai

--
You received this message because you are subscribed to the Google Groups "emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to emscripten-disc...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/CAN%3D%3DuddahRRPV02%3DT9TaQd2%3D3YzxqHDBAqg8%3DsWJL-Taqh4-SQ%40mail.gmail.com.

Sebastian Theophil

unread,
Jan 7, 2022, 9:01:50 AM1/7/22
to emscripte...@googlegroups.com
Hi Alon,

thank you very much and it's great to hear that you find this interesting. I would be very interested in integrating this with emscripten of course. How should we start this process? There are probably a few things that still need to be implemented for a good MVP, so to speak. 

Regards
Sebastian 

Alon Zakai

unread,
Jan 12, 2022, 1:06:46 PM1/12/22
to emscripte...@googlegroups.com
I just have some general thoughts at this point. Curious to hear your ideas and other people's.

Maybe a nice starting point would be to make it easier for people to experiment with typescripten, to get feedback. Could we add minimal integration on the emscripten side to allow that, just a new option perhaps (marked experimental), and that uses a module from npm? (Or does this need more things than can be packaged in npm?)

A thought I had is whether we could eventually replace embind with typescripten (or at least the part of embind that supports calls from C++ to JS). That is, if the core "JS object" class in typescripten had the same API as embind vals do (for accessing things in a *non*-type-safe way, using strings). Do you think that could work? If we could replace parts of embind it would strengthen the case for upstreaming, I think.

- Alon


Sebastian Theophil

unread,
Jan 15, 2022, 4:03:24 AM1/15/22
to emscripte...@googlegroups.com

Am 12.01.2022 um 19:06 schrieb Alon Zakai <alon...@gmail.com>:


I just have some general thoughts at this point. Curious to hear your ideas and other people's.

Maybe a nice starting point would be to make it easier for people to experiment with typescripten, to get feedback. Could we add minimal integration on the emscripten side to allow that, just a new option perhaps (marked experimental), and that uses a module from npm? (Or does this need more things than can be packaged in npm?)

Sounds good to me. More practical experience is certainly needed most at this point. I could package typescripten for npm. Practically all TypeScript interface files are on npm as well. Maybe it would be convenient to have a command line argument to specify which type definitions to pull. 


A thought I had is whether we could eventually replace embind with typescripten (or at least the part of embind that supports calls from C++ to JS). That is, if the core "JS object" class in typescripten had the same API as embind vals do (for accessing things in a *non*-type-safe way, using strings). Do you think that could work? If we could replace parts of embind it would strengthen the case for upstreaming, I think.

I could try that out. I think it should work. The base js object already aggregates emscripten::val anyway. 

I hope to have some time in the coming weeks to work on typescripten and will hopefully send a PR on GitHub. 

Regards
Sebastian 

Alon Zakai

unread,
Jan 18, 2022, 12:19:05 PM1/18/22
to emscripte...@googlegroups.com
That sounds great!

- Alon

Reply all
Reply to author
Forward
0 new messages