Live data from Hacker News

TypeScript Without Transpilation (2021)

incrementalelm.com

21–30 of 46 posts

Re: TypeScript Without Transpilation (2021)

#21
// @ts-check works until you need to do an assertion, a cast, a predicate, pass an explicit type to a generic method, etc., then it gets very annoying. I only ever use it if I’m writing a single self-contained and relatively short script and can’t be bothered with a build step.

Re: TypeScript Without Transpilation (2021)

#22
post #3

Sorry for being that guy, but this should probably be called "typechecking without transpilation". What ends up being written is not TypeScript syntax (which does require transpilation to run). JSDoc is awesome for incremental adoption though, I've migrated a few codebases this way without too much pain.

Not TypeScript the language, but TypeScript the typechecker program. “Typescript without transpilation” is still perfectly accurate.

Vouched. This is the point of the thing - the typechecking benefits come from running `tsc` on your code (or VSCode will do it for you in the background and show you linter errors if you have typescript installed somewhere it knows about).

Incidentally I've been doing my JS projects this way for 2-3 years and I really dig it.

Re: TypeScript Without Transpilation (2021)

#23
post #14

I'm using this setup at the moment, mostly because I work on legacy code base that has no good types yet. Typically you would do jsconfig.json though, which is same as tsconfig.json but allowJs is already set. Mostly stylistic change, but some tooling might benefit for having jsconfig instead of tsconfig.

Yeah, all three settings this article mentions at the top are correctly defaulted when using a jsconfig.json file instead of a tsconfig.json file: allowJs, checkJs, and noEmit.

Additionally, I don't know about other editors but I know that VS Code subtly adjusts some workspace detail defaults based on the presence of jsconfig.json over tsconfig.json.

It's slightly more than just a stylistic change, but yeah there's no "wrong answer" if you prefer tsconfig.json to jsconfig.json, especially if you think there may be a subset of files you wind up preferring TS syntax and want to transpile/type-strip in the future (dropping the "noEmit"). (If for some reason you need to do a bunch of generics, for instance, that's a lot easier with type-stripping from TS syntax than trying to squeeze in JSDoc. Also, maybe you'll bump into a situation where TS downleveling is helpful, for a while I had projects that needed downlevelIteration to support certain IE/Safari versions and letting TS downlevel that was a lot easier and cleaner than the Babel-based alternatives.)

Re: TypeScript Without Transpilation (2021)

#25

Earlier quoted context omitted.

Could that improve execution performance?

No. First paragraph of the proposal: > This proposal aims to enable developers to add type annotations to their JavaScript code, allowing those annotations to be checked by a type checker that is external to JavaScript. At runtime, a JavaScript engine ignores them, treating the types as comments. The problem is handling errors. If the engine does a full analysis of every code path to ensure the types aren't violated,…

> If the engine doesn't do a full analysis up front but instead checks every time a type is used, you end up with, at best, roughly the same performance characteristics that current JIT engines already have.

There are definitely optimizations that JIT engines can do, pre-optimizing the "shapes" expected of objects, especially with respect to rare/optional parameters. In some of the current JITs an extra parameter that hasn't been used before/in-a-while drops code from a faster path to a slower one. Knowing ahead of time that parameter might show up eventually can lead to the faster path in more cases. You still get slow path penalties for type violations and other unexpected shapes, but that benefit of more "shapes" hitting the fast path sooner (less "learning time" for the expected shapes by the JIT, because it can assume the type is a correct description) may overall be a benefit over untyped performance.

Worst case, yeah, it is "roughly" the exact same performance characteristics, but best case it does buy some performance benefits.

That said, yeah the current proposal to TC-39 does not include that for a number of good reasons and it would need follow up proposals to provide type semantics that JITs could count on. Though if the first proposal succeeds, such follow up proposals become more likely. (We are seeing that a bit in Python as some follow up PEPs have converged some of the base type semantics, though still not yet with runtime performance in mind.)

Re: TypeScript Without Transpilation (2021)

#26

Earlier quoted context omitted.

No. First paragraph of the proposal: > This proposal aims to enable developers to add type annotations to their JavaScript code, allowing those annotations to be checked by a type checker that is external to JavaScript. At runtime, a JavaScript engine ignores them, treating the types as comments. The problem is handling errors. If the engine does a full analysis of every code path to ensure the types aren't violated,…

> If the engine doesn't do a full analysis up front but instead checks every time a type is used, you end up with, at best, roughly the same performance characteristics that current JIT engines already have. There are definitely optimizations that JIT engines can do, pre-optimizing the "shapes" expected of objects, especially with respect to rare/optional parameters. In some of the current JITs an extra parameter tha…

Does this mean the JIT engine will be compiling code that it would not have otherwise? That in itself might end up being a small penalty, given that so much code is never a hot path anyway.

If not, I'm not seeing the type annotation adding value that the engine doesn't already have from existing runs.

Re: TypeScript Without Transpilation (2021)

#27

Confused about the mentions of Elm. What does this have to do with Elm?

It's an Elm blog. It starts off with saying that even when writing Elm, you still have to drop in to Javascript.

Okay... that's not saying much though? Why even mention it? I don't know anything about Elm but this looks like a blog post about JS, not Elm, but it's talking about Elm right from the start as if that's an important distinction to make here.

It's like those recipe blogs that have to give you their life story before telling you how to make a meatball. Just get to the damn point and skip the bullshit, please.

Re: TypeScript Without Transpilation (2021)

#28

Earlier quoted context omitted.

It's an Elm blog. It starts off with saying that even when writing Elm, you still have to drop in to Javascript.

Okay... that's not saying much though? Why even mention it? I don't know anything about Elm but this looks like a blog post about JS, not Elm, but it's talking about Elm right from the start as if that's an important distinction to make here. It's like those recipe blogs that have to give you their life story before telling you how to make a meatball. Just get to the damn point and skip the bullshit, please.

The website is called "incrementalelm.com".

Re: TypeScript Without Transpilation (2021)

#29

Earlier quoted context omitted.

> If the engine doesn't do a full analysis up front but instead checks every time a type is used, you end up with, at best, roughly the same performance characteristics that current JIT engines already have. There are definitely optimizations that JIT engines can do, pre-optimizing the "shapes" expected of objects, especially with respect to rare/optional parameters. In some of the current JITs an extra parameter tha…

Does this mean the JIT engine will be compiling code that it would not have otherwise? That in itself might end up being a small penalty, given that so much code is never a hot path anyway. If not, I'm not seeing the type annotation adding value that the engine doesn't already have from existing runs.

It should mean compiling (a lot) less code in the best cases. (JITs compile early and often.) Roughly, today:

1. JIT sees a function take a lot of objects {x: int, y: int}

2. JIT compiles a hot path of that function for {x: int, y: int}

3. JIT sees an object of {x: int, y: int, z: int}, goes to a slow uncompiled (deoptimized) path of that function

4. Over time JIT sees a bunch more of {x: int, y: int, z: int} and compiles a hot path for that function

5. Over time the JIT sees that the compiled hot paths of {x: int, y: int} and {x: int, y: int, z: int} share a bunch of code and get called roughly evenly and further compiles an even more optimized shared hot path of {x: int, y: int, z?: int}

Note that this isn't the case in every JIT, or every runtime and mileage always varies when talking about JIT optimizations, but that's a roughly common way to look at that.

In theory, knowing ahead of time that expected/preferred shape is {x: int, y: int, z?: int}, the JIT could skip steps 1-4, start from step 5, just one "perfect" hot path for the most common expected object shapes, and see fast code for every {x: int, y: int} and {x: int, y: int, z: int} object the function takes, right from "the beginning" of run time.

(It might still fall back to a deoptimized path for a strange, rare {x: string, y: int} or something like that, but it still has a better hot path for what should be the more common/likely arguments. Which is why worst case and possibly average case having type knowledge doesn't perform better than existing JITs. But it can still enhance the best case.)

(ETA: Of course, Step 0 is determining that function is on a hot path in the first place. That is assumed to be the same in both cases with/without type information.)

Re: TypeScript Without Transpilation (2021)

#30
JSDoc comments are definitely not the “best of both worlds,” they are a limited and verbose subset of typing. I would only use them for specific reasons, like I’m in a hostile ecosystem that dogmatically doesn’t want any build steps (like WebGL/WebGPU engines).
Post reply on HN