Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typescript Support #1921

Open
saulshanabrook opened this issue Feb 21, 2019 · 5 comments
Open

Typescript Support #1921

saulshanabrook opened this issue Feb 21, 2019 · 5 comments

Comments

@saulshanabrook
Copy link

Do you support generating Typescript type annotations based on the models?

@kgrgreer
Copy link
Collaborator

No we don't. FOAM doesn't actually generate JS code. Instead it dynamically builds JS prototype and class objects using object and function composition. I realize this is a tricky thing for people to grasp if they aren't familiar with the concept. For Java and Swift we statically generate code which is easy to understand, but for JS we just build up the class and prototype directly by setting slots and using defineProperty. This is much faster as it doesn't involve having to generate and then parse code. You could add a typescript outputter, but then this would decrease the size advantages you get from FOAM (which you might be okay with, given you're not using FOAM now). As way of example, the FOAM Gmail client is almost exactly 100 times smaller than the non-FOAM version. This is because JS is powerful enough to let us expand the models on the client side rather than on the server or as part of the build. However, FOAM does have run-time type-checking where it will check types of arguments and properties if you annotate this information in your model. If you're interested in trying this type of type support instead or, or in addition to, Typescript, then let me know and I'll provide you with some documentation on how to use it.

@bshepherdson
Copy link
Contributor

It's worth pointing out that for compatibility with other, handwritten TS code, you could generate Typescript code from FOAM models that is "weightless". Interfaces and some other type declarations in TS are only used in the TS compiler, and don't survive to the JS output.

@saulshanabrook
Copy link
Author

saulshanabrook commented Feb 21, 2019

@kgrgreer Thank you for the explanation, this is very interesting. I haven't seen this pattern before in JS so I will have to look into it more to understand it. It actually does make some sense, I am used to this pattern in Python, i.e. using metaprogramming to build useful classes at runtime without having to pre-process.

In Python-land to integrate these kinds of features with static typing requires adding an extension to MyPy (example adding Dataclasses support). Do you think something similar would be required to have this framework integrate nicely with TypeScript?

EDIT: I guess there are two options here for Typescript support without having to pre-generate some typings:

  1. Somehow add a "plugin" to TypeScript that has special support for these concepts (not sure if you can do this).
  2. Make TypeScript expressive enough to be able to express the type creation based on these concepts. I don't know enough about either system to understand how (in)feasible this is. (issue on adding support for class decorators to TS Analysis support for metaprogramming decorators microsoft/TypeScript#26347). "Increasing expressivity" and "Enabling popular JS patterns in a type-safe way" are both on TypeScript's six month roadmap.

@kgrgreer
Copy link
Collaborator

It's been many years since I looked at TypeScript, but doesn't it convert the type checks to run-time asserts using a small library? FOAM does the same thing if you provide types. You can see this done in debug.js. You could do the same thing but call out to the typescript assertion library instead. Although, that wouldn't help your typescript code calling into FOAM. For that you could follow @shepheb's idea above. Or just use FOAM's type checking instead of TypeScript (but you may already have a large investment in TypeScript).

@bshepherdson
Copy link
Contributor

I was thinking about this more, recently.

TypeScript has excellent support for adding compile-time-only types to an existing JavaScript library, since that's a common use case.

Since FOAM already has a type system, and ~all of (user-visible) FOAM is modeled, we could add .d.ts TypeScript declaration files as a codegen target.

Then you could work with FOAM from TypeScript by using the same JS code that builds things dynamically at runtime, but your TS code is statically checked against the generated type declarations. That yields the best of both worlds, with strong type-checking and no added runtime overhead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants