Live data from Hacker News

Node.js adds experimental support for TypeScript

github.com

531–540 of 570 posts

Re: Node.js adds experimental support for TypeScript

#531

One thing to note is that it is impossible to strip types from TypeScript without a grammar of TypeScript. Stripping types is not a token-level operation, and the TypeScript grammar is changing all the time. Consider for example: `foo ( x )`. In TypeScript 1.5 this parsed as (foo (x)) because bar&baz wasn’t a valid type expression yet. When the type intersection operator was added, the parse changed to foo (x) which…

Does TypeScript have some disambiguating syntax like turbofish?

Re: Node.js adds experimental support for TypeScript

#532
post #527
post #519

Earlier quoted context omitted.

Turning on EVERY safety feature won't mitigate the unsoundness because the problem goes beyond stuff like `any`.

I know, but it just doesn't matter enough. Believe me, I'm signed up to the idea of theoretical rigour, the argument for soundness is part of what originally won me over (along with previous good experiences with Flow on a smaller project, and the support for gradual adoption). I will continue to be drawn to languages and tools that have a strong theoretical foundation. But in this particular case, today, when compar…

I think the real answer is adding actually sound types to JS itself.

One of the biggest revolutions in JS JITS was the inline cache (IC). It allows fast lookup and specialized functions (which would be too expensive otherwise). These in turn allow all the optimizations of the higher-tier JITs.

The biggest problem of Flow and TS is encouraging you to make slow code. The second you add a generic to your function, you are undoubtedly agreeing that it is going to be accepting more than 4 types. This means your function is megamorphic. No more IC. No more optimization (even worse, if it takes some time to hit those 5+ types, you get the dreaded deoptimization). In theory, they could detect that your function has 80 possible variations and create specialized, monomorphic functions for each one, but that's way too much code to send over the wire. That kind of specialization MUST be done in the JIT.

If you bake the types into the language via a `"use type"` directive, this give a LOT of potential. First, you can add an actually sound type system. Second, like `"use strict"` eliminated a lot of the really bad parts of JS, you can eliminate unwanted type coercion and prevent the really dynamic things that prevent optimization. Because the JIT can use these types, it can eliminate the need for IC altogether in typed functions. It can still detect the most-used type variants of a function and make specialized versions then use the types to directly link those call sites to the fast version for even more optimization.

I use TS because of its ubiquity, but I think there's the possibility for a future where a system a little more like Flow gets baked into the language.

Re: Node.js adds experimental support for TypeScript

#533

Earlier quoted context omitted.

> multiply that small amount of work by the number of users who will have to repeat it This is probably where we have the biggest difference in our calculations. I know there's a lot of pain in legacy CJS systems, but from my view (which is maybe more "browser-oriented", which is maybe a bit more Deno/Bun-influences, which comes from a "Typescript-first" mentality going way back to 0.x) it is more legacy "giant balls…

Aight let me chime in here. I'm a game developer. I make web games. We run our games with a simple nginx server that simply serves the wasm. We have some JavaScript libraries we use. They have to be raw dog .js. I don't even know what your "ejs" or "cjs" acronyms mean. We use the discord JavaScript SDK. Discord only ships it as a node module or as .ts. It's a pain in our ass to update because we don't know what those…

I'm on your side. No one should have to care about the difference between ESM (.mjs) and CJS (.cjs). CJS should just be dead and we only need one .js again. If you are following the Discord JS docs and using modern JS syntax `import` and `export` statements (if you are "raw dogging" it, have you heard the good word of ?) then none of the above conversation applies to you, congratulations! That's the winning modern JS and you are one of the majority of users using it. The conversation above is about the old dead JS (CJS) and why people are still outputting the old dead JS today when it doesn't matter to people like you or I that just want plain modern .js files (and .ts files and simpler tsconfigs).

Re: Node.js adds experimental support for TypeScript

#534

Earlier quoted context omitted.

Jsdoc is honestly fine for simple and smaller projects. But yeah, it’s definitely not nearly as expensive while being anywhere as succinct.

JSDoc is for docs, TypeScript is a static type checker. How can these tools be used interchangeably?

You can configure tsconfig.json to read JSDoc and error on invalid types so that you effectively get the same behavior as writing typescript.

Re: Node.js adds experimental support for TypeScript

#535

Earlier quoted context omitted.

Why are you still transpiling to .cjs in 2024? ESM is supported in every LTS version of Node now. We can kill CJS, we have the power.

i wish it was that easy. i keep trying to default to esm on node projects but the ecosystem is not there yet, at least in the context of server side nodejs stuff.

It's one reason to consider a switch to Deno or Bun, but at least to maybe at least check JSR before NPM these days. The ecosystem for server-side ESM exists and is growing at a rapid pace, but it's sometimes hard to separate the active maintained npm packages from the legacy ones in the server-side ecosystem. (Browser ecosystem is definitely more ESM hungry.)

That said with "type": "module" in my own package.json files, I've so far never had a problem importing legacy CJS npm packages into ESM, other than the Types are more likely to be wrong (because packages that only publish CJS are more likely to also not publish their own types) or at least inaccurate for the current import approach (returning only "synthetic default" instead of individual exports, for example). That's a bunch of papercuts having to attempt multiple imports until you understand what shape Node is giving you of that CJS import, but after those papercuts I feel like interop is generally smooth sailing in today's Node.

Re: Node.js adds experimental support for TypeScript

#536
post #532
post #527

Earlier quoted context omitted.

I know, but it just doesn't matter enough. Believe me, I'm signed up to the idea of theoretical rigour, the argument for soundness is part of what originally won me over (along with previous good experiences with Flow on a smaller project, and the support for gradual adoption). I will continue to be drawn to languages and tools that have a strong theoretical foundation. But in this particular case, today, when compar…

I think the real answer is adding actually sound types to JS itself. One of the biggest revolutions in JS JITS was the inline cache (IC). It allows fast lookup and specialized functions (which would be too expensive otherwise). These in turn allow all the optimizations of the higher-tier JITs. The biggest problem of Flow and TS is encouraging you to make slow code. The second you add a generic to your function, you a…

Maybe! I see where you're coming from. That sounds like a long and painful road, still, though, from what is still a very dynamic language. Do you have a rough idea of how much more time/space-efficient a typical JavaScript program could be through this?

Re: Node.js adds experimental support for TypeScript

#537
post #468

Earlier quoted context omitted.

Most parsers don't actually work with "lines" as a unit, those are for user-formatting. Generally the sort of building blocks you are looking for are more along the lines of "until end of expression" or "until end of statement". What defines an "expression" or a "statement" can be very complex depending on the parser and the language you are trying to parse. In JS, because it is a fun example, "end of statement" is d…

Thanks for the response, but I'm aware of the basics. My question is pointed towards making language parsers resilient towards separately-evolving standards. How would you build a JS parser so that it correctly parses any new TS syntax, without changing behavior of valid code? The example snippet I added is designed to violate the rules I could come up with. I'd specifically like to know: what are better rules to sol…

In your specific case:

1. Automatic semicolon insertion would next want to kick in at the } token, so that's the obvious end of the statement. If you've asked it to ignore from `as` to the end of the statement (as you've established with your "ignore to the end of the 'line'"), that's where it stops ignoring.

1A. Obviously in that case `bar(null` is not a valid statement after ignoring from `as` to the end of the statement.

2. The trick to your specific case, that you've stumbled into is that `as` is an expression modifier, not a statement modifier. The argument to a function is an expression, not a statement. That definitely complicates things because "end of the current expression" is often a lot more complicated than ASI (and people think ASI is complicated). Most parsers are going to have some sort of token state counter for nested parentheses (this is a fun implementation detail of different parsers because while recursion is easy enough in "context-free grammars" the details of tracking that recursion is generally not technically "context-free" at that point, so sometimes it is in the tokenizer, sometimes it is a context extension to the parser itself, sometimes it is using a stack implementation detail of the parser) and you are going to want to ignore to the next "," token that signals a new argument or the next ")" that signals the end of arguments, with respect to any () nesting.

2A. Because of how complicated expression parsing can get, that probably sets some resiliency bounds on your "ignorable grammar": it may require that internally it still follows most of the logic of your general expression language: balanced nested parentheses, no dangling commas, usual comment syntax, etc.

2B. You probably want to define those sorts of boundaries anyway. The easiest way is to say that ignorable extensions such as `as` must themselves parse as if it was a valid expression, even if the language cannot interpret its meaning. You can think of this as the meta-grammar where one option for an expression might be ` ::= 'as' ` with the second expression being parseable but ignorable after parsing to the language runtime and JIT. You can see that effectively in the syntax description for Python's original PEP 3107 syntax-only type hints standard [1], it's surprisingly that succinct there. (The possible proposed grammar in the Type Annotations proposal to TC39 is a lot more specific and a lot less succinct [2], for a number of reasons.)

[1] https://peps.python.org/pep-3107/

[2] https://tc39.es/proposal-type-annotations/grammar.html

Re: Node.js adds experimental support for TypeScript

#538

Earlier quoted context omitted.

It looks like the team has already considered this in one regard > There is already a precedent for something that Node.js support, that can be upgraded seperately, its NPM. Node bundles a version of npm that can upgraded separately, we could do the same with our TypeScript transpiler. > We could create a package that we bundle but that can also be downloaded from NPM, keep a stable version in core, but if TypeScript…

As long as Node understands to use the project-specific version of TypeScript (i.e., the one in node_modules or the PNP equivalent), that should be fine. But it would be a step backward to need to globally upgrade TypeScript (as you do with npm), since some older projects will not be compatible with newer versions of TypeScript. Ask me how I know. ;)

At first I thought that's not a big deal, I could manage that with `nvm`. But I think you're right, you really want it to pick up the project-specific typescript so that you're using ONE version of typescript for type checking, execution, and more.

Re: Node.js adds experimental support for TypeScript

#539

Earlier quoted context omitted.

Great work, many thanks! Out of curiosity, what do you see as next steps, and what possible futures do you see for typescript in the node- and overall JS-ecosystem?

this is the roadmap https://github.com/nodejs/loaders/issues/217 . We talked with the typescript team and we will give each other continous feedback on the progression. We made sure to take some precautions in order to avoid breaking the ecosystem. I still think in production, js is the way to go, so users should always transpile their ts files.

Could you expand on why transpiling is the right long-term strategy for production? I get that right now you don't support some TS-specific features like enums. Is that the concern? Those seem like a few legacy exceptions, new TS capabilities will be "just javascript".

Not transpiling would be great to reduce toolchain complexity and eliminate the need for sourcemaps just to understand exceptions and debug.

Re: Node.js adds experimental support for TypeScript

#540
post #61

Earlier quoted context omitted.

With this approach, do you still use Python's standard syntax for type hints? def mersenne(p: int): return 2**p - 1 Or, given there's no need for the type hints to be checker-friendly, do you make them more human-friendly, e.g: def mersenne(p: 'prime number'): return 2**p - 1

While it’s not common (from the source code I’ve reviewed over the years), some people make a new type with a name and use that in the definition: ``` from typing import NewType # Create a new type for some_prime SomePrime = NewType('SomePrime', int) def process_prime(value: SomePrime) -> int: return value ``` However, this isn’t nearly as common as simply using a more descriptive argument name like “prime_number : i…

> One of the big advantages to type hinting in Python is that it feeds the IDE a lot of information to increase auto-complete functionality

Yeah, until this discussion I thought the main benefit of type hints was earlier detection of bugs via static checking. Now though, I'm getting the impression that the bigger benefit is enabling IDE features such as autocomplete.

That helps me understand better why I haven't found type hints as useful as others seem to - I don't use an IDE. My use of Python is limited to small scripts which I write in a simple text editor.

Post reply on HN