
Runtime type information for JavaScript - stablemap
https://medium.com/fhinkel/runtime-type-information-for-javascript-b134faac3c0a
======
Schampu
I've recently worked on something similar, which uses dynamic analysis to be
able to collect type informations and many other data which is only available
at runtime.

Runtime type checking: [https://maierfelix.github.io/Iroh/examples/type-
checking/](https://maierfelix.github.io/Iroh/examples/type-checking/)

JavaScript -> Flow conversion:
[https://maierfelix.github.io/Iroh/examples/auto-flow-
types/](https://maierfelix.github.io/Iroh/examples/auto-flow-types/)

It's also possible to turn the runtime control-flow of running JavaScript into
a playable game:
[https://maierfelix.github.io/src2game/](https://maierfelix.github.io/src2game/)

~~~
jw-
Really interesting stuff! I tried out some higher-order examples:

INPUT >>> function add(f, b) { return f(b); };

let a = add(function(x) {return x + 1}, 3);

OUTPUT >>> function add(f: function, b: number): number { return f(b); };

let a: number = add(function(x: number): number {return x + 1}, 3);

and I noticed that the flow type annotations are added to the call site,
rather than on the argument f in the definition of add. Are all the types that
you generate first order?

------
jw-
I've done some work on dynamic type checking for JavaScript and the tricky
part is always when things start going higher order; sadly this is often
omitted from examples.

The motivation for dynamic checking was often because many JavaScript programs
couldn't be given any useful static types. With the great work on Flow and
TypeScript I'm starting to become convinced that we'll just be able to
statically check most JavaScript programs in the future and get decent types
out.

~~~
seanwilson
> The motivation for dynamic checking was often because many JavaScript
> programs couldn't be given any useful static types.

I like this quote: “Dynamic typing: The belief that you can’t explain to a
computer why your code works, but you can keep track of it all in your head.”

I don't get it personally, when you've got decent type inference the number of
type annotations should be minimal and compile-time errors mean things that
would cause a runtime crash anyway.

------
josephg
Cool! I've been wanting something like this for a long time for IDE-suggested
type annotations. "From test execution it looks like parameters x and y are
always numbers. Add type annotations automatically?"

Or a linter could give optimization recommendations: "Warning: Function
deoptimized at runtime because in 2% of calls to this function parameter x is
an object."

~~~
antiufo
The JavaScript intellisense engine of previous versions of Visual Studio used
to instrument a sandboxed JS engine in order to extract the shape of objects
and methods used in the code, so it also worked when unusual idioms for
structuring code were used. Recent versions use instead the TypeSript
compiler, with support for plain JavaScript and flow analysis.

~~~
WorldMaker
Recent versions of Typescript also pay attention to JSDoc type hints and will
even check them for you and start reporting "lint errors" if you just add a
`// @ts-check` magic comment to the file. It can be a particularly quick way
to bootstrap a project with a lot of JS a file at a time towards static
typing. (Personally, I still prefer the "rip off the bandaid" approach of just
renaming every JS file to TS and fix compile errors until it builds, but it's
great to have options.)

------
batmansmk
The code has to be executed for getting the type information (hence the
runtime).

It is less powerful than inferring types, and won't help I think from an IDE
perspective, except in the edge case of refining types that are too broad; but
it will be based on one execution path.

~~~
jw-
You could easily use unit tests to get better coverage.

------
tryckbarpingvin
Being able to auto generate Typescript definitions is exciting

~~~
jhurliman
You can try [https://github.com/Microsoft/dts-
gen](https://github.com/Microsoft/dts-gen) now.

~~~
jw-
As far as I can tell this isn't dynamic, it just builds an AST. Am I missing
something?

