Search code examples
javascripttypescriptflowtypepure-js

How to interoperate from js to Typescript?


I have question regarding usage of Flow, Typescript and similar superset javascript language.

How do I call something that is written in Typescript from pure js code?

Does the mechanism look anything like the interoperation of Scala and Java? Like following article.

https://blog.akquinet.de/2011/07/20/integrating-scala-components-in-a-java-application/


Solution

  • Typically a Typescript library would be compiled into .js and .d.ts files, former featuring compiled code and latter featuring Typescript typings AKA type declarations.

    If you use Typescript in your source code, typically the compiler should pick up on these .d.ts files in the process of compilation (resolution of module dependencies).

    If you use pure Jabba-the-Hutt-script for your source code, these .d.ts would come in handy for your editor to provide suggestions, error highlights and stuff. If you use Babel (which, if you do, might be as well substituted for a full-blown tsc) there will prolly be more of the signature rechecking at the compilation step.

    And about Flow - who cares about Flow unless you are Evan You working on Vue 2.x.x in 2016.

    But actually no, I went out to read the docs on the website and it looks like the compiler outputs a version of the js file with your type annotations stripped, and it exists in a form of a Babel plugin and a standalone application called flow-remove-types. There are no mentions of typing information being preserved after the compilation process, contrary to what tsc does.

    As good as my experience with Node environment programming goes, kinda looks like you are supposed to link the library statically, using the source code itself to get the type information, since after the compilation it's stripped, duh.

    But come on, as I mentioned before, Flow is to be considered deprecated anyway and there is no reason to use it over Typescript.

    Old answer below

    Your analogy of this with the Java and Scala relation is invalid. What is more like it is the relation between JVM instruction set and the Java (or Scala, or practically every single language that gets compiled into the JVM bytecode) itself.

    In that, suppose you write something in the bytecode and you need to call some signature somewhere in the realm of Java. Stuff to consider:

    1. Access semantics, i.e. where the Java stuff in available in plain JVM syntactical environment, what is it called, is there any custom calling convention atop of the JVM's rules
    2. ???
    3. I will add more in an edit if anything comes to mind.

    So when it comes to Typescript (and Flow too AFAIK) we have the following:

    1. No custom calling conventions, exceptioning is plain JS.
    2. Functions are transpiled 1 to 1.
    3. Classes transpilation depends on the target, but the signature and usage should round up essentially equivalent from ES5 to ESNext.
    4. Not sure how namespaces are implemented, but I bet 15 Rubles that all the child members of a namespace end up as props of an object that is accessible as the name of the namespace, duh.
    5. Working with module system should be straightforward.
    6. ???
    7. I will add more if I remember anything crucial, but these should cover like 95% of the cases.

    Also, please note that there is no such thing - "calling Java code from the JVM bytecode" in the same manner as there is no such thing as "calling C# code from .NET CIL" as well as "calling C code from LLIR". The source code is a goner, what's left is its compiled form. You may or may not sort of "source-map" the compiled version to the source, essentially allowing for navigation and even debugging, but still, the code you are calling is not the same thing as your source code.

    P.S.: Everything I've written above is NOT advised, it's a hack. You are relying on the output of the compiler and hence its particular implementation. What you probably should do instead is compile your js code using Typescript and have the compiler mind the interoperation.

    P.P.S.: Last time I checked, facebook/flow is deprecated, ever since the release of TSC and you are strongly advised to never ever start a project using NOT Typescript.

    P.P.P.S.: CommonJS is not a superset of Javascript. CommonJS is not even a language.