| That's a strangely puritanical viewpoint. I wouldn't say it's core to the design of the language. I'd say it's a key design decision for the development of the compiler, but those are two different things. Also, I don't understand what you mean by "it wouldn't be TypeScript". Languages change. They change all the time. Did adding nullish coallescing before it became availalbe in JavaSciprt? It's also not true that TypeScript is purely static and doesn't have any runtime component. There are a bunch of helper sort of functions that TypeScript can optionally include, so there is some precedent for having runtime-oriented code generated by TypeScript, rather than just eliding type information after successful static checking. So perhaps there could be a syntax for imposing runtime-checking as an optional element. Something like: interface Point {
x: number;
y: number;
}
async function getPointFromAPI(): Promise<Point> {
const request = await fetch("/api/points/current");
const point = await request.json<Checked<Point>>();
return check point;
}
Type `Checked<T>` would signal to the compiler that type information for T needs to be made available at runtime, and the `check` keyword would perform the check and "unwrap" the type to a bare reference to T.I don't know what it would look like, but it would be a huge value add. |
It is absolutely core to the language. TypeScript's core value proposition is that you can take vanilla JavaScript and use it from TypeScript without any overhead, incrementally migrate to TS, or maintain a heterogeneous codebase as long as you want.
If you take away seamless zero-overhead JS interop, the language you have is radically different from TypeScript. To the degree that any language has any identity at all, that would be a pretty fundamental change in its identity. Like taking objects from Java or pointers from C.
To the best of my knowledge, no one has figured out how to have a language that allows mixing dynamic and static typing without either massive runtime overhead or giving up soundness. You basically have three options:
1. Allow dynamic types to flow into statically typed code
2. Soundness inside the statically typed code
3. Tolerable runtime overhead when using dynamic code from static code
But you only get to pick two. TypeScript, Dart 1.0 and other optionally typed languages give you 1 and 3 at the expense of 2. Dart 2.0 and other statically typed languages give you 2 and 3 at the expense of 1. Gradually typed languages like Typed Racket give you 1 and 2 at the expense of 3 (and are rarely used in practice because of it).
You're asking for TypeScript to just add 2. People have been trying to figure out how to get all three for decades but no one has succeeded yet [1].
[1]: https://blog.acolyer.org/2016/02/05/is-sound-gradual-typing-...