upvote
The main problem with TypeScript is the default compiler flags are not safe. I understand having things weak when you’re getting the ecosystem up and running, before you have wide adoption. You don’t want to throw too many red squigglies at early adopters and cause them to give up. But these days the default should not allow any. No implicit any. No explicit any. The stdlib should not use it. JSON.parse() should return either unknown or a recursive union that defines all valid JSON structures.

I believe it’s largely because of these defaults that the idea that TypeScript isn’t really checking types persists. Without the any type, or loose undefined and null checks, your types are as validated as they can be. The only failure point is deserialization or an import which doesn’t type check. And deserialization has this problem in every language.

When you compile C to machine code the executed binary isn’t checking types. This is no different from Typescript that’s been compiled to JavaScript.

reply
Even with strict flags on, there are failures. A trivial example:

  function mutateArray(
    arr: (string | number)[]
  ) {
    arr.push(1);
  }
  const a: string[] = ["one", "two"];
  mutateArray(a);
a is now a string[] with a number inside
reply
deleted
reply
Very interesting. I’m shocked the typescript creators built a system with this failure mode. I guess the solution here is to have tsc change the type of “a” after the call to mutateArray, unless the arr argument is marked as readonly.

Is there a name for this failure mode?

reply
In TypeScript it's called "bivariance", which sounds very programming language theory like, but is not a term typically used in academic contexts, since it is unsound almost by default. It's described here: https://www.typescriptlang.org/docs/handbook/type-compatibil...
reply
I think the problem is the union argument type - intuitively we read "array of strings OR numbers", but actually it means "array of strings AND numbers". Probably generics would be more appropriate here, with the type param constrained to string or number. Then tsc would also complain about pushing a number without checking the item type before.
reply
If it's an "array of strings AND numbers", then it should not be allowed to call the function with a string[], because those are different types.
reply
deleted
reply
I'm not aware of a name, but I'm also curious if there is one because I had a hard time searching for it.

I came across it on ThePrimeagen's YouTube channel: https://youtu.be/u1WmiqlrqL0

reply
I asked an LLM and it described the problem as "covariant typing of mutable collections" or "unsound covariance". I'm not mathematically educated in this area but that sounds right?
reply
> You don’t want to throw too many red squigglies at early adopters and cause them to give up.

That's not the reason.

TypeScript's main design goal was to enable developers to gradually introduce types in codebases that spent years being written purely in JS.

There's still demand for this feature and those who start off with TypeScript set their own config anyway.

I've dealt with people using all kinds of escape hatches, but 2/3 of the time it's caused by lack of proficiency in the language.

The rest is either someone being in a hurry or just not serious about their job.

reply