I don't understand. All languages, without exception, must compile down to a "worthless untyped jargon". Only assembly can execute.
Javascript is a garbage layer of broken standards, a worst of breed language that shouldn't have to exist between a strict typed higher level language and lower level bytecode, but everything on the web now needs to be built on top of it, compile to it first, and run through one of a few JS engines. You can never build a full fledged language on top of something that has to go through JS... so TS, coffescript, et al are always going to be pseudo typed but not truly solid or permanent solutions.
Ultimately I think ECMA standards will finally move toward strict types in JS, and in a decade more we'll have something that for all intents and purposes is exactly what Flash was in 2009.
Sure, but if your typed language is sound you shouldn't have type errors at runtime. Not having type at runtime is not a problem, type erasure is nothing new and works really well in OCaml.
> You can never build a full fledged language on top of something that has to go through JS... so TS, coffescript, et al are always going to be pseudo typed but not truly solid or permanent solutions.
Rescript and Elm are really solid, OCaml can compile to JS too, Scala and F# too. Granted, only Elm has been built on JS at first, others were adapted (Rescript is like half and half), but they're all solid.
> Ultimately I think ECMA standards will finally move toward strict types in JS, and in a decade more we'll have something that for all intents and purposes is exactly what Flash was in 2009.
I think the idea here is to offer WASM as a compilation target. Trying to gradually type JS leads to really complex systems (TS types) because people did all sorts of crazy things with JS. I wouldn't like this to be the base on which we build other languages, or the web in general.
TypeScript, by design, does not produce nor introduce any "noisy defensive code": the point of TypeScript was that type-safety in JavaScript can be achieved without any runtime cost.
The only significant code-gen that TypeScript does do by itself is stuff relating to ECMAScript modules (e.g. wrapping and repackaging your TypeScript module for other module systems).
...with the exception of when you take a modern TypeScript compiler and specifically instruct it to target ES3 (lol) or perhaps some older variants of ES5 - at which point the code `tsc` generates is still so minimal you'll still need to bring-your-own polyfill/monkeypatch libraries. This is stuff like reimplementing the spread-operator or `for(of)`, and so on.
the web runs on JavaScript because it's extremely forgiving and therefore stable. there can be lots of errors and things keep chugging along.
...and when types are within TypeScript's sphere-of-influence the compiler is largely able to deduce types without needing assertions or type-checks.
...or so you think! But there's two problems:
1. TypeScript's type system is unsound: so there are times when the compiler will let you do some (for example) contravariant array mutation, even though that's almost essentially guaranteed to crash at runtime if the rest of the system makes incorrect assumptions about the type-variance of the array/collection. So having the type-guard function available to assert to tsc that whatever array operation you performed is safe, you wouldn't need to do that in pure JS.
2. Type-guards are essential for when you're working with values that pass through an interface (because that necessarily means some loss of typing information has occurred), so the type-guard function is needed to recover that static information - and while this approach does also apply to JS, in some situations where if your code is the factory of subclasses that pass through an interface (e.g. so `MyComplicatedSubclassForRockAndRoll` appears as `MusicSubclass`) then in JS a blind "reinterpret-cast" of the object is fine - but TypeScript really doesn't want you doing that and again, having a type-guard function is just to keep the compiler happy - and even if it is possible to mathematically prove that the `object` type-cast is correct (because theoretically static analysis can see on both sides of an interface) but TypeScript isn't perfect and there are cases where we really do know better than the compiler, but we don't want to just make it unsafe and untyped - instead we want to keep the typing and we want to keep the compiler happy, but doing it this way (a type-guard) is not only easier than suppressing warnings and ignoring your sense of guilt but they're invariably genuinely useful a few months down the line when someone made a change that the type-system spotted and prevented from compiling (and so going into production), whereas it would be very easy to (for example) unintentionally introduce vulnerabilities because even with near-100% test coverage, because adding brand new functionality to a project (even if it said functionality doesn't work) it won't cause any tests to fail (at least, until tests for the new functionality are completed).
If it's an external API, do the same thing except it probably needs a more manual approach.
This is not something that's in anyway unique to typescript. The difference is JavaScript is designed to fail gracefully using coercion whereas most other languages and runtimes abort and throw exceptions.