Hacker News new | ask | show | jobs
by disease 1655 days ago
> As TypeScript is a core part of the Deno ecosystem, we are also very interested in pushing for even closer alignment of TypeScript and JavaScript in the future.

I've wondered why the frontend community hasn't gotten together and said, "The next version of JavaScript - is TypeScript!" I've been using TypeScript for five years professionally now and cannot understate how much easier it has made large frontend (not just Web, but mobile and desktop) projects. Surely enough thought and work has been put into TypeScript to make it the next standard.

7 comments

If TypeScript becomes the next version of ECMAScript, then browsers will have to support it. The day that TypeScript is supported directly on end-user machines instead of going through a developer-controlled compiler pipeline is the day that almost all evolution of TypeScript stops.

There's not really much positive value out of having browsers run TypeScript natively. The main feature is static checking, but static checking doesn't benefit end users. When I go to my bank's website, if their front-end code has a type error, it's not like I can fix it right then and there.

The type system is mostly a developer-time feature, so it makes sense to leave it out of the core runtime environment.

In other words, think of JavaScript/ECMAScript more like the architecture that browsers support. That needs to be slow-moving since it's deployed across billions of devices. TypeScript then just targets that.

Adding TypeScript directly to JavaScript would improve the world to about the same degree that adding C++ features directly to x64 machine code would.

This is not true. There are a number of ways that TypeScript's type-checking can be subverted at runtime, particularly when dealing with APIs that return JSON. You have to trust that the API has returned exactly what you are expecting, or write your own very detailed validation scripts. It's similar to the sorts of testing one would do in vanilla JavaScript without TypeScript, but now executing all the time at runtime.

As a developer, in the case of an API change that violated my assumptions, I would personally prefer my applications to fail-hard at the point of the API call, rather than to have my scripts run merrily on and only error in some other code far away from the root-cause when one of those assumptions fails.

However, I have a lot of hope that runtime type checking based on auto-code generation around TypeScript's interfaces could be developed in a future version of TypeScript.

This would be a big (but exciting) departure from the current TS goal of "Impose no runtime overhead on emitted programs." [1]

Recently, I've been using Zod [2] and find it to be a satisfying equivalent: you define a schema, and then you get both a TS type AND a JS parser/validator (which works as a TS typeguard).

[1] https://github.com/microsoft/TypeScript/wiki/TypeScript-Desi... [2] https://github.com/colinhacks/zod

Zod looks super cool. I'll have to check it out in depth.
TypeScript is an optionally typed language. It's core to the design of the language that the static type system is purely statically typed and doesn't come into play at runtime.

You could argue that that's not the best kind of language for users. I wouldn't disagree. I work on Dart which used to be optionally typed but now has a fully sound type system with runtime checks.

But that's orthogonal to whether browsers should support TypeScript directly. If they supported a statically typed language that had the runtime checks to be sound, that might be a great language, but it wouldn't be TypeScript.

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.

> I wouldn't say it's core to the design of the language.

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-...

No, I'm not. You're way overthinking this and your attitude is weirdly gatekeepy. I'm asking TypeScript to implement a shortcut feature for the tedious, boilerplate code we already write to use type guards to inspect objects from APIs before passing them on.
This is also why Deno running TypeScript directly is a bad idea.
The difference is a that a developer has a lot more control over what version of Deno their server-side app runs on than they do what version of a browser their client-side app runs on.
This isn't really true in the wider ecosystem. Yes, the app developer does, but the library developer does not. As Deno adopts newer versions of TypeScript and config options libraries can fail to compile. This is compounded by the lack of a package manager so that references to specific versions and CDNs are hardcoded into dependents.

All with essentially no benefit over running plain JS with associated typings.

They don't though. They transpile it behind the scenes
Same thing with the same problems. The difference being that Deno isn't going to have the same no-breaking-changes policy that the web does.
Types in TypeScript are great but if JavaScript ever wants to add types it has to be something like a real programming language types in which you can use types in runtime as well. Like in a catch clause I can assert the type of the error and do things with it once that assertion is done. Many other useful things when types space and runtime space are not totally separate.

ES4 was the first shot at adding types to JavaScript which failed due to how big the ambitions were. I'm not sure if there is any more appetite for adding types to JS tho.

In very very serious big applications like a 3D editor you can fall back to WebAssembly and use your favorite typed language. For smaller apps TypeScript is good enough. This way JavaScript stays simple and lean.

"real programming language types"

There are a few languages where types only exist (for the most part, though with exceptions and hacks here and there) at compile-time, like Rust, C++ or even Haskell IIRC.

JS objects already have runtime types, and you can use them in catch clauses.

    try {
      …
    } catch (e) {
      if (e instanceof FooError) {
        …
      } else if (e instanceof BarError) {
        …
      } else {
        throw e;
      }
    }
There was once a Mozilla extension (https://web.archive.org/web/20200111091805/https://developer...) that allowed you to abbreviate the above to

    try {
      …
    } catch (e if e instanceof FooError) {
      …
    } catch (e if e instanceof BarError) {
      …
    }
It was never standardized, but since it’s just syntactic sugar, if there were demand, it could be standardized without bringing in an entirely new type system.

There would be at least two problems with using TypeScript types for this. Firstly, TypeScript types are unsound in a number of intentional and unintentional ways, meaning that it’s possible for the compile-time and runtime types to disagree, even in fully typed code. Secondly, TypeScript can express many types that cannot be tested at runtime; for example, there is no way to tell whether a function accepts a string as an argument, or to guess the inner type of an empty array.

*>...use types [at] runtime..."

Two things. First, TS conceives of itself as having no runtime component. If it did, I think people (including the TS devs) would be more confused.

Second, I'd say rather we need a runtime type system. In fact I've tried my hand at writing one in the most minimalist way possible, and have been working on it recently [1]. The type system is explicit in that a type is a JSON like object, similar to JSON schema, but 100x less code.

[1] https://github.com/javajosh/simpatico/blob/master/friendly.h... This is effectively the test harness for the module.

> it has to be something like a real programming language

It's a nice feature request but there's no one feature that makes a programming language "real".

TypeScript is great and everything, but Microsoft owns the standard and the single functioning checker, and haven't published a specification or even a grammar.
The TypeScript checker/compiler is Apache 2.0 licensed, so I'm not sure there's room to complain, unless you disagree with the direction they're taking the project:

https://github.com/microsoft/TypeScript/blob/main/LICENSE.tx...

Nobody disputes that TypeScript is open source, but there’s still a vast difference between a single open-source implementation and a specification that’s suitable for standardization. The implementation inevitably has bugs, and there needs to be a way to decide which bugs are actually “features” that other implementations will need to emulate.

(Here’s the specification for ECMAScript, for example: https://tc39.es/ecma262/)

To be clear, I am not bashing Microsoft here—just pointing out a reason that TypeScript can’t be declared “the next version of JavaScript”, which is the context of this thread.

Would expanding wasm capabilities be a better long term option here instead of supporting TS directly? Opening the browser up to a whole lot of languages, including Typescript (AssemblyScript exists already).
TypeScript is still experimenting with its type system and it has numerous edge cases. I could be more in favor to specify and support a minimal subset of TypeScript rather than the entire TypeScript. Basically we could start by enabling type annotations, enum declarations, and type-aliases.
TS design goals and non-goals [1]

It's very much designed to be a layer of abstraction over JS.

I am as much a fan of TS, however, it's not likely ever going to be the thing that it's really close to being.

[1] https://github.com/Microsoft/TypeScript/wiki/TypeScript-Desi...

Because then ability for typescript to be agile would be destroyed. JavaScript can’t be changed as easily as typescript.