
TypeScript – The Myth of the Superset - jbandi
http://blog.jonasbandi.net/2016/10/myth-of-superset.html
======
BoorishBears
At work I needed a fast scripting environment for Android. Not everyone who'd
be scripting for the application knew Lua (or Squirrel) so I went with J2V8
(Java bindings for V8).

The first problem I ran into was documenting the API defined on the Java side
of things. I tried Jsdoc, but it was cumbersome for what I was trying to do
(expose type information).

I tried Typescript on a whim and fell in love with it. The people who only
know Js could still use Js, but the Ts scripts so easy to reason about I
disabled Js support in my build system (which uses Browserify and some in-
house signing tools to compile the script files into one package I can easily
load into V8).

The people who were used to Js couldn't just write everything they would Js as
this article describes, but what they couldn't write seemed to be stuff that
would break a lot of compile time checks. It was a little battle to get one
guy to stop using <any> everywhere, but 9/10 times that he came to me with a
broken script, it was something that satisfying the compiler without <any>
would have found the issue.

And the Java side now looks so much cleaner because we have a compiler that
can check that we're sending it the right types, so there isn't as much work
trying to cast everything from Object to different representations it could
have in Js. I define interfaces that the Java side implements with 'declare'
and get that type checking and autocomplete for exploring the API for free,
which is another huge win.

I've noticed a lot of JVM-Js integration (Kotlin has Js interop iirc) and I
think Typescript is really great there. Flow looked interesting, but it felt
like its approach is more targeted towards existing code bases trying to
migrate to it, and we didn't have that constraint

------
Eridrus
I think this is a less relevant issue now that tsc can include plain .js files
in builds. I think the spirit of being very close to JavaScript and being
easily convertible from one to the other is more important than being a strict
superset.

------
k__
Polymorphism of JavaScript functions is a bit of a pain point in TypeScript, I
think.

I often got some query methods, that deliver different types of objects, which
share a parent class. Like GameObject, Player, Enemy.

    
    
        const player = getGameObject('playerId')
    

Now player will be typed like the return type of getGameObject. If I now try
to set an attribute, specific to `Player`, it will fail:

    
    
        player.mousePosition = [1, 2] 
        // won't work, because GameObject doesn't have a mousePosition
    

Also, setting the type of player to Player, will fail too:

    
    
       const player : Player = getGameObject('playerId')
       // getGameObject could return an Enemy
    

So I have to tell TypeScript, that I know better

    
    
       const player = getGameObject('playerId') as Player
       // Forces TypeScript to treat the return value as Player

~~~
BoorishBears
Why is that last line a problem at all?

~~~
k__
It implies that TS doesn't fully understand JS.

~~~
BoorishBears
I wouldn't say that, that line is pretty much the main value proposition of
the language though, is it really "not understanding JS" as much as extending
it?

If you really want it to understand Js you could just cast to Any, but to me
it's huge that you can do what you do in that last line. Instead of guessing
that Player has a mousePosition property, after casting you get told it has
one, and get it's exact type.

~~~
k__
To me it seemed the other way around. By casting, I'm telling the compiler
that it has a mousePosition property.

But I think you're right. This is an simple example and the Player object
could have a huge bunch of properties I don't need to guess later, I just need
to cast and be done with it.

------
smt88
tl;dr The TypeScript compiler is strict, so it won't let you compile
JavaScript that contains what it assumes are mistakes. I love that about TS,
and it's one of the main reasons to use it.

The package incompatibility is different, but I've never had trouble using any
JS or TS package in TS, so it doesn't seem to be a practical issue.

