
TypeScript 3.5 - DanRosenwasser
https://devblogs.microsoft.com/typescript/announcing-typescript-3-5
======
sli
I would really love to enjoy TypeScript, especially now that they've added
HKTs, but I am constantly running into type errors when the types clearly
match, leading to weird workaround code where the type of some key in some
object is specified as:

false | 'x' | 'y' | undefined

Meaning passing in `'x'` should work just fine. But instead, it specializes it
to just a string, then throws a type error. The workaround requires me to
write the following value to avoid a type error:

'x' as 'x'

This is not the only time I've run into this kind of problem -- I run into
this problem _regularly_ \-- this is just the simplest version of it that I've
experienced. I just cannot take a type system seriously when workarounds like
that are needed.

Add to that, in many cases being unable to import a JS library in that doesn't
include typedefs, and I fail to see how TS can be considered a superset of JS.
It's certainly sold that way, but it's clearly not totally true. TS+React
requires --noImplicitAny, which cannot be worked around (it's labeled as being
required due to a platform limitation).

I also find Microsoft's documentation of TypeScript to be very poor (and has
no search feature -- I'm sure they have some convenient excuse for that). I
tend to learn how things work from random Github comments or source code after
reading the documentation over and over. What is `declare` used for _in
practice_? They don't really say, they just say it's for declaring things, and
give highly specific examples.

Maybe I'm the odd one here and maybe I'm missing some piece of information
that a lot of TypeScript developers have, but I've yet to find it and given
all the choice I have these days, there are numerous languages I would choose
well before TypeScript.

~~~
phiresky
> in many cases being unable to import a JS library in that doesn't include
> typedefs

Make sure you have "allowJs": true in your tsconfig.json. Otherwise, you'll
have to create a minimal file with `declare module "xyz";`

> I fail to see how TS can be considered a superset of JS

You have to interpret all TS "errors" as warnings for that to be true (which
they mostly are considering tsc still emits code regardless of non-syntax-
error errors)

> I just cannot take a type system seriously when workarounds like that are
> needed.

Your problem really just seems to be that the type inference does not have
magical powers. There is no other programming language that has union types as
powerful as TypeScript (as in discriminating by whatever you want), but yeah
when you do `return {x: 1, y: 2}` the compiler doesn't always know whether you
mean to return an object where the type of x is `1` or where it is `number`.
In some cases it could be better still, but doing this in general is just not
possible.

~~~
ElFitz
> There is no other programming language that has union types as powerful as
> TypeScript

How about Swift and OCaml? ReasonML comes to mind too. Haven't tried actively
comparing any of them though.

~~~
tomp
OCaml/Reason have _discriminated_ unions, which means that you have to
explicitly specify which _variant_ of the union you're using, such as

    
    
      type union = Bool of bool | Char of char | Nothing
    
      let (x, y, z) = (Nothing, Bool true, Char 'x')

~~~
saagarjha
Is this not what enums with associated values are?

~~~
tomp
Probably... but in any case TypeScript also supports _naked_ (edit: I just
made up the name) unions, where you _don 't_ need to declare them upfront, and
where values of different types can be included directly. Such as:

    
    
      let a = random() ? 'a' : 1
    

TypeScript infers type

    
    
      string | number

~~~
marton78
This is still a discriminated union, only that the discriminator is provided
by Javascript and is thus hidden: it's `typeof`.

~~~
tomp
Yeah, that's the runtime perspective... but for the type system, they're
different... with the "naked" union being much harder (as they're non-
algebraic - `a | b | b` always equals `a | b` and might even equal just `a`
for some values of `a` and `b`)

------
lioeters
Wonderful! My favorites from this release:

\- Omit helper type

\- Smart Select (allows editor to expand/shrink selection based on syntactic
construct)

\- Extract to type alias (smart refactor of function parameters to their own
type)

\- Performance improvements

------
Roboprog
It sounds like type inference for object literals is coming along, even if
there a few quibbles about some of the defaults on literals mentioned here.

Did they ever get a solution in place for partial function application (e.g. -
as for Ramda.js)?

When this gets to the point where the only place I have to define explicit
types is for JSON data read from the network, I’ll consider using it.

I know I’m in the minority, but I’d rather NOT have any type checking than
have to read through Java-esque drivel (at least most modern languages put the
types after the identifier like Pascal does, rather than before like C). In
practice, I don’t spend much time chasing type errors, but do spend too much
time reading through MEGO inducing verbiage which I would just as soon not.

~~~
jasonhansel
I think it's best to require type annotations at interface boundaries, but not
within implementations. That way, changes to the interface are obvious, but
excessive verbosity within a module is limited.

------
hermanradtke
I wish there was a better testing story for TypeScript. ts-jest is slow
because it does not benefit from incremental compilation. Having tsc compile
everything creates a dist/ folder with tests, fixtures, etc and causes all
sorts of subtle issues to be worked around. Also, trying to use tsc-watch and
something like jests watch runs into all sorts of weird race conditions though
at least the build and the tests complete in about 1 second.

I looked into combining tsc-watch and jest, but jest does not currently
support a public API. tsc-watch already emits an event on success which should
be able to trigger (an already running!) test runner to incrementally test
again.

------
PaulBGD_
Does anyone here have experience with slow TypeScript builds? I've updated to
use --build and incremental, but it still takes 3s+ to build 30 files on a
8700k clocked at 5GHz.

~~~
DanRosenwasser
Typically, TypeScript type-checks `lib.d.ts` every single compilation which
can add at least half a second of build time. It will also do a full check of
`.d.ts` files in your dependencies, which can also be pretty heavy.

We're considering ways we can avoid a full type check:
[https://github.com/microsoft/TypeScript/issues/31417](https://github.com/microsoft/TypeScript/issues/31417)

In the meantime, you can try out turning on the `skipLibCheck` compiler option
to see if that helps at all, but be warned that it might not catch conflicts
across multiple files.

~~~
spankalee
Is the check of `lib.d.ts` not helped by --incremental?

------
mattigames
The 2 big things missing on typescript:

1) Operator overloading

2) Runtime type checking of JSON payloads (on dev env at least)

Can't believe in 2019 every library has to create its own way to add 2
elements of the same class together e.g dataframe1.addTo(dataframe2) vs
dataframe1 + dataframe2

And the most common error that it should help catch during development is that
you get a JSON and you cast it but it means nothing cause on runtime the JSON
can be something completely different and nothing breaks until is somewhere
else hard to debug, I get that Microsoft don't want to add runtime overhead
but it should be possible at least on development mode.

~~~
farnsworth
> 1) Operator overloading

Please, please, please, no.

~~~
mattigames
You know it would be completely transparent right? Just gets transpiled into
.__add__(obj)

~~~
watt
We already saw this play out in Scala. People end up abusing these to create
absolutely unreadable "DSL"s. Even when it's tastefully done, for example the
"!" and "?" operator for messages in Akka, it's not better than the names
"tell" and "ask".

~~~
mattigames
Fair enough.

