An approach to optimizing TypeScript type checking performance
edgedb.com
edgedb.com
How much it actually speeds up the type checker depends on how hard it is for the type checker to infer the return type. And that depends on the return expression, but I don't think there is a single hard and fast rule here. But, if you already have a named type for the return value of the expression, I would absolutely annotate it explicitly when possible. Sometimes the inferred type won't be really the type you intend, and there might just be a more clear type you want to use for communication/documentation purposes.
I've had typescript break on me when using libraries like elysia that go full send on their templates.
I suppose WASM enables layered languages like AssemblyScript comes close in many ways but it's also a bit too separated from the primary webpage use case.
Not a fan.
You can, for example, declare your type and check at runtime if some object matches the type.
The Dart approach just gave us yet another unimaginative nominally-typed language.
TypeScript is complex, but it’s also incredibly cool if you’re into compilers. Engineers do their best work when there are limitations imposed, in this case the need to add types to JS.
...which has the implication that what TypeScript is actually giving us is a REPL. Our code is increasingly "evaluated" by our IDE, in our hover-overs
I think this is a major reason people like TypeScript so much
Of the performance tips at the end, the interface vs. intersection type one is the suggestion I find the most annoying. That’s because it’s the most common pattern, and using interfaces is conceptually a lot less clean. It’s terrible that a linter effectively forces you into writing worse code.
I really wish the TypeScript team got their act together and fixed the performance of their linter somehow. Finding clever optimizations, porting to Go/Rust, whatever is necessary. (3rd-party reimplementations won’t do: they’ll never catch up with a corporate-funded moving target.)
The big issue is dealing with a structural highly expressive type system, the language of implementation is only going to be a constant slow down (but that constant can be large).
So the relatively simple answer would be no, it would not be faster with C# (or Go which would likely have a similar speed to C#).
.net is available on all systems where developers work with their code.
I do wish that Typescript would offer some tools to make it more ergonomic to write performant unifying code (I kind of despise conditional types, especially when you then use it to create the partially valid types by resolving to never). But I think it would also be very helpful to get people to understand that your types are their own little program that run and have performance characteristics. It's not magic!
There's been some handwaving about performance not being due to it running in JS (because at the end of the day unification is unification is unification and it takes time), but looking at the Typescript codebase in general and poking at it, I can't help but wonder how much of even the heavier stuff is "death by 1000 cuts" on that front.
Maybe give https://gcanti.github.io/fp-ts/ a go?
I really think that TS itself should offer syntax more or less matching what that lib does at the type level, but this is a bit of a maximalist request.
As for fp-ts all APIs have examples/tests that show their usage.
It’s possible there are other aspects of the APIs that differ in meaningful ways, but last I checked virtually all of the libraries with similar functionality (and there are many) have roughly the same concepts until your schemas themselves get deeply complex.
It’s not a very full featured Result, but you can wrap it with your own type.
Can’t find the links but one of the reasons I’ve seen people move away from xml has been due to the speed in parsing when compared to json or csv.
That's a bad take - typescript enables tooling like refactoring/navigation/completion that goes far above a linter. Development tools are just better with typescript vs JS.
I'll note that most of the upsides are also subjective.
I never understood this. It takes maybe 10 minutes to set up TypeScript in a project if you’ve done it before.
Compared to all the other times involved (time to learn typescript, time saved debugging and writing tests for type errors) the setup time is a total non-issue.
Even other dynamic languages started moving in this direction due to the benefits of having type annotations brings to tooling/development experience overall.
Complaining that you have to tune it for performance is like complaining that your runtime code isn't automatically maximally performant without a little tuning.
Anything you name has either less support or different cons.
It’s early days there but with the JS ecosystem being the mess that it is I’m actively interested in finding alternatives to at least evaluate.
One approach I’m enjoying so far is Dart which has two relevant compilers (I.e Dart to JS and Dart to WASM) but they have the advantage that you can just use Dart like normal which is a clear 10x improvement over writing either JS or TS and you only have to worry about the specific layers where you need to interop with JS code and you can wrap that up in really nice ways.
For example here’s an example of Dart interacting with browser APIs: https://github.com/dart-lang/web/blob/main/example/example.d...
I'm not here to challenge your decisions, but there's a real dearth of information on this topic and knowing when something applies to your situation is hard. Someone writing a web server has different problems and concerns than someone writing React or Vue websites, or someone processing IO on a microcontroller. Can you go into some details about your situational how and why? I'm curious to hear more about the nature of these pure-JS-for-performance libs and what was measured as non-performant in the TSC output?
It's not like we aren't still doing TS. We're achieving this through the use of JSDoc (and possibly ECMAScript type annotations in the future). Though a little non-performance related added advantage is that when our developers click on "go to implementation", they'll get to the actual code. It has advantages and disadvantages as I said. You'll really, really, need to know the inner workings of JS to outdo the big transpilers, and you're not getting a lot of help working with it (especially not if you're using VSC). I'm not sure you would want to do this in JS at all for the most part, it's just that we are primarily TS developers. I'm the only one who knows C well enough to use it reliably, as an example. Which isn't exactly "maintainable" for the business.
So as I said in at the beginning, I think your gut reaction is correct 99% of the time, but it is an alternative the GP I was replying to asked for.
I have been tracking PRs like [2] that change the definitions to better be optimised by V8. But the effects are only ~30% and not the 50x that might be achievable by native.
[1]: https://github.com/kaleidawave/ezno/actions/runs/10299707325 [2]: https://github.com/microsoft/TypeScript/pull/58928