
Announcing TypeScript 3.1 - DanRosenwasser
https://blogs.msdn.microsoft.com/typescript/announcing-typescript-3-1/
======
monkmartinez
Is TypeScript worth learning? I know that is a loaded question, but I need to
ask it anyway.

I am super frustrated with lack of screens for python. I don't want to pigeon
hole into an ecosystem where I am limited to a certain platform like
Java/Kotlin or even (dare I say) Swift (no real web, still need JS). As a
single developer, mostly hobby, I want options for all the things!!!

I have been migrating my Python scraping to JavaScript with node, puppeteer,
and it has been quite illuminating, and the speed is ridiculously better.
Furthermore, I can easily turn my scrape into a desktop app with electron with
an api that is consumed by a mobile app with react-native. Long story short, I
can now think about making some of my Python ideas into cross platform desktop
apps with mobile versions as well. Not super easy with Python.

The question is would TypeScript be even better for a long term bet?

~~~
sacado2
It solves all the issues I have with Javascript, that are all related to its
weak and dynamic type system: awkward, unwanted type conversions all around,
tons of "undefined is not a function", and lack of IDE integration. So, yes,
it's definitely worth it, even for small projects. And it's not like it's hard
to learn once you know javascript, anyway. It's nothing more than a superset
of the language.

~~~
aikah
> that are all related to its weak and dynamic type system

It doesn't make JS strongly typed though. It's still possible to compare
different types, it still allows type coercion,truthiness and what not. It add
type definitions, but it does not turn Javascript into a strongly typed
language.

~~~
alangpierce
It actually does disallow various type coercion operations that you can do in
JS, even when they're arguably useful. For example `1 == "1"` doesn't
typecheck:

[https://www.typescriptlang.org/play/index.html#src=const%20x...](https://www.typescriptlang.org/play/index.html#src=const%20x%3A%20number%20%3D%201%3B%0D%0Aconst%20s%3A%20string%20%3D%20'1'%3B%0D%0Aconsole.log\(x%20%3D%3D%20s\)%3B)

So while there are still things like truthy/falsy values, the type system is
stronger (not just static) in some sense compared with JS.

------
the_other_guy
For me, Javascript now means Typescript, thanks to all who contribute to this
great language!

------
erokar
TypeScript is fine. I used it for about half a year when wokring on an Angular
app. But for new projects with React now I seldom see the need to include it.

Sure, TS gives you a little bit better autocompletion in VS Code, you can
document your function signatures a little bit better and you can catch a few
trivial type errors — but it also has some costs: Extra set up, extra build
steps, the need to also import type definitions when including a library,
cluttering the code with interfaces and type definitions.

I find the extra value it gives over PropTypes in React is pretty low. And
while types in function signatures arguably increase understanding, elaborate
interface definitions, sometimes in their owen files with the need to import
them, can clutter up the code and be a detriment to readability. Also, VS
Code's auto completion is very good even without TS.

~~~
pferdone
Static vs dynamic typing aka catching type errors on compile and not on
runtime. Easily refactor code and all references there of. I would also say
that I‘m faster using TypeScript BECAUSE of autocompletion, implicit code
documentation through types, etc. The cost you listed are solved during the
setup of a project.

I can just talk for myself, but I started a project at work and pushed for
TypeScript. We now have automatically generated Swagger-clients fully typed,
with a GraphQL layer infront of it with generated types for queries. Basically
everything is typed now and I don‘t have to test or check incomming data or
guess what kind of object I have to expect from our backend. The tooling is so
good now, that the benefits outweigh any setup hassle you have upfront IMHO.

~~~
erokar
Good points. I'm not against using TS, I just think the it should be
aknwoledged that it does have costs. The nice thing about TS is that once
included you can use it as much or as little as you like (for function
signatures only, for instance).

I also think project scope and team size is important -- the larger these are,
the more I would consider TS.

------
theodorejb
Seems like a pretty small release in comparison to previous updates. Probably
a good thing, though - it demonstrates that the language as reached a very
mature state with few remaining gaps.

~~~
pjmlp
Now it just needs to become the official JavaScript's strong mode. :)

~~~
daveidol
Seriously: this language is amazing. I have to admit I was a holdout for a
while, but TS has been fantastic to work with compared to Flow

~~~
k__
Good to know.

I dad the impression Flow was the better approach, but using it wasn't nice.

~~~
WorldMaker
For a brief period Flow had more type algebra (type unions and intersections)
and better inferencing, but Typescript has greatly shrunk the gap between type
system capabilities where the differences are much fewer, and rarely anything
that matters for most projects.

Flow was popular for the ability to put all of its type annotations in JS
comments and not need a transpilation pass. Typescript also added a mode that
supports that.

Flow was popular for the slipstream integration into Babel as the type-
stripper was just an "ordinary" Babel plugin. Typescript now supports this as
well.

So for the most part a lot of the old impressions that Flow was the better
approach are out-of-date, and par-for-par Typescript is an equal approach (if
not a better approach, depending on your preferences/needs, and due to things
like the fact that there are vastly more Typescript type definitions than Flow
definitions in the npm wilds now).

~~~
k__
Ah.

Yes, I read about how TypeScript is a more classical approach, and Flow would
use "flow based" typing or something, which was a more modern approach. Also,
it came out of the box with non-nullable types.

While I had the impression the TypeScript language designers didn't deem these
features to be important, they added them anyway.

~~~
WorldMaker
I don't think it was ever a matter of "not-important", Typescript and Flow
started from two different perspectives and took different routes to get to
what today is a somewhat more converged place.

Overall, I also don't think it's "modern" versus "classical" that much. In
terms of the different philosophies it's "language" versus "linter" /
"compiler" versus "observer", and there is a huge spectrum of options there.

Typescript starting from a place of prioritizing "green field" development at
first, where teams had the option to start fresh or similar. Like CoffeeScript
or Dart, it wanted to provide a good way to organize and develop new code.
(Unlike CoffeeScript or Dart, the "pure superset" approach still provided
easier migration; I worked on several projects where conversion was simply
rename .js to .ts and then fix compiler warnings until it worked again.)
Taking the compiler approach also provided an early focus on providing some
transformations to the code. In Typescript projects I typically don't feel a
need for Babel, because Typescript handles everything I want in terms of
"downlevel" transforms to support the version of JS in browsers.

Flow starting from a place where you've got a huge line of code investment
into an existing codebase, can't "stop the world" to migrate and absolutely
need to start "linter style" evaluating data types.

Over time Flow has picked up more reasons to use a cleaner syntax for type
annotations than what just comments alone can deliver, driving more Flow
projects to adopt Babel transforms for that (in addition to whatever other
Babel transforms a project wants).

Over time Typescript has wanted to get better at migrating existing JS code.
The team proved the language worked great for greenfield projects, and got a
lot of interest from customers internally and externally to extend that make
it a lot easier to do grayfield work. Also, Typescript found its "pure
superset" proved better than expected at evaluating almost all JS. This pushed
Typescript to power more and more IDE intelligence features for both JS and TS
(in an increasing number of IDEs, beyond even the Visual Studio family). That
in turn pushed more JS mode features and support in the language, and
increasingly better type inferencing and flow control analysis especially when
working in large forests of untyped JS.

As for the typing systems themselves, "modern" versus "classical" almost is
descriptive, from a certain point of view, modulo the fact that both typing
systems are "ancient". Typescript started from a type system that started out
seeming more in common with the C++/C#/Java family of "Object Oriented" typing
systems, whereas Flow started from a place of being much more directly
inspired by the "functional" ML family of type systems. (Though calling this
more "modern" than the ALGOL-style "OO" type systems belies the fact that the
ML family dates to the 70s and about all of our type systems have equally
ancient roots; and that like Typescript versus Flow, in a larger sense they've
done almost nothing but slowly converge over the intervening decades, learning
and growing from each other in both directions.)

Typescript didn't start with a lot of the more abstract or higher level type
algebras, partly it seems because they wanted to work towards it from a
"pragmatic" standpoint of build something that works, find out where the new
pain points, build something that works to fix those, and iterate as so forth.

Flow started very directly with a powerful abstract type system (with well
known inferencing techniques) that was theoretically sound, but arguably not
as easily pragmatic to what you might consider the average developer, which is
exactly why you would expect Flow to have an early lead from the perspective
of the type system.

The convergence towards very similar type systems after all that work
shouldn't be surprising either, as the drive for more robust type descriptions
has indeed pushed Typescript to continually pragmatically iterate, and the
realities of the dynamic JS language Typescript tries to type involves a need
to describe with types a very wide and diverse range of behavior.

Both approaches have their advantages. Arguably, Typescript's "pragmatic"
focus I think has helped Typescript end up with the lead that it has in type
definitions across the JS ecosystem. Both because the ramp to more
advanced/abstract type features is easier for a wider spectrum of developers
(in my experience even relatively junior developers can write a Typescript
definition file relatively well; Flow that's not necessarily the case from
what I've seen, which Flow tries to balance by making inferencing more
powerful and definition writing less necessary) and also that the
pragmatic/iterative approach in the language itself reflects in a more
"perfect is the enemy of the good" attitude in type development in general.
(It's fine for a type definition to only describe ~90% of the
API/behavior/quirks of a library if that's good enough to get the job done.
You can come back and tighten up that remaining 10% in the next pass, or when
the next type system features gives you a knob you need to help get it more
accurate to how it behaves.)

That turned into maybe more of a ramble than I intended, but maybe there's
some useful perspective there.

~~~
k__
Thanks for that thoughtful writeup :)

------
tlarkworthy
I love Typescript and the type system is getting pretty powerful. I would like
to use it more in commandline utilities, but then I find the JS event loop
makes sequential commands annoying, or REPLs need trampolining etc.

There is nothing in typescript that actually ties the type system to the event
loop. I would love the Typescript language applied to a runtime that was ok
with blocking IO.

~~~
rictic
For CLIs I end up doing something like:

async function main() {

}

main().catch(e => { console.error(e); process.exit(1); });

Async/await is what I want, more than blocking, because frequently to make a
CLI fast I need to do things in parallel. I'm often working against a network
filesystem though, so doing as much FS stuff in parallel has a big payoff.

------
yawgmoth
What is the lowest ceremony way to start building a TypeScript SPA? I would
love to avoid Webpack if I can :)

~~~
pietro
Parcel has first class support for TypeScript. It's amazingly simple:
[https://hackernoon.com/zero-config-typescript-bundling-
with-...](https://hackernoon.com/zero-config-typescript-bundling-with-parcel-
ef76fabcbfe3)

~~~
GijsjanB
First class? Parcel uses Babel to transpile. Ugh. [https://github.com/parcel-
bundler/parcel/issues/954](https://github.com/parcel-
bundler/parcel/issues/954)

------
dlbucci
Glad to see that adding properties to functions will be easier now. I've been
tripped up by that a few times before, and was always surprised at how painful
it was to type such a relative common JS pattern.

------
velox_io
I was kind of hoping that they would get rid of null or undefined (or both).
While I understand that null and undefined are not the same, are both truly
needed? Seems like a missed opportunity to make the language cleaner. They
seem redundant when you have exception handling, which I think makes the flow
of the code easier see.

Could they be removed?

~~~
saurik
Part of the premise (and I think this is very noble) is that they are trying
to be descriptive of what JavaScript is, not prescriptive of what anyone
wishes JavaScript should have been. (That said, I don't even understand what
you mean by saying that both null and undefined seem redundant when you have
exception handling... how do you represent "this exists or it doesn't exist"
in the type system if you can't do a union type of "X" and "null"? I don't see
how exception handling has anything to do with null/undefined.)

~~~
kroltan
> how do you represent "this exists or it doesn't exist" in the type system if
> you can't do a union type of "X" and "null"?

Like this, pick your flavor:

[https://doc.rust-lang.org/std/option/enum.Option.html](https://doc.rust-
lang.org/std/option/enum.Option.html)

[https://docs.oracle.com/javase/8/docs/api/java/util/Optional...](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html)

[https://docs.microsoft.com/en-
us/dotnet/api/system.nullable-...](https://docs.microsoft.com/en-
us/dotnet/api/system.nullable-1)

[https://wiki.haskell.org/Maybe](https://wiki.haskell.org/Maybe)

If you don't want to follow links: Instead of having nulls, have a type which
is either a discriminated union (not possible in JS) or is a (isPopulated,
value) pair, and accessing the value is an exception if isPopulated=false.

Granted, that would be an extremely breaking change for a JS-compatible
language, which would make it in fact incompatible. But answering the
question, that's it.

------
ZeikJT
Another case of just blatantly ignoring semver[0] and only increasing the
minor version while including backwards incompatible changes!

[0] [https://semver.org/](https://semver.org/)

------
novaleaf
self plug: i wrote a "corelib" for typescript:
[https://www.npmjs.com/package/xlib](https://www.npmjs.com/package/xlib)

right now it's only meant for nodejs use (it's too big for browsers) but I use
it successfully in my production code, and have been using it for years, so
it's got that for it :)

i plan to add proper browser support (minification, tree shaking, etc) when i
do my next client side project, but that's still at least a few months off.

------
crudbug
Can we have a CLR backend now ?

