28 ms·
Completely picking nits: Node doesn’t understand types at all, the distinction is between what TypeScript now calls “erasable syntax”[1] versus syntax excluded
by eyelidlessness 1y ago
Completely picking nits: Node doesn’t understand types at all, the distinction is between what TypeScript now calls “erasable syntax”[1] versus syntax excluded by that. The exclusion of enum isn’t likely to affect many projects (because enum has long been panned by most users). Same with namespace. By far the most likely incompatibility is “parameter properties”, ie class fields assigned in the constructor signature.
1: https://www.typescriptlang.org/tsconfig/#erasableSyntaxOnly https://www.typescriptlang.org/tsconfig/#erasableSyntaxOnly
- alpinisme 1y agoSome people hate enums but they’re the only easy form of nominal typing in typescript, and for that alone you can pry them from my cold dead hands.
- eyelidlessness 1y agoI agree completely. But I also know I’m in the extreme minority. Now I just use erasable syntax even on my personal projects because it’s less friction. Maybe someday the enum proposal in TC39 will mix this up a bit!
- matt_kantor 1y agoI find that for most of my use cases, branded types[1] are close enough to nominal (especially if you use a private `unique symbol` as the brand). [1]: https://www.learningtypescript.com/articles/branded-types https://www.learningtypescript.com/articles/branded-types
- alpinisme 1y agoI did say easy and by that I also meant lightweight. You can just use a string not an object with a relatively esoteric symbol in addition to whatever serializable value you need.
- goodoldneon 1y agoWhy is nominal typing desirable?
- jy14898 1y agoexample: type FireNuke = boolean; type DontFireNuke = boolean; function perhapsFireNuke(action: FireNuke); you wouldn't want to call perhapsFireNuke with DontFireNuke, even though the types are compatible
- veidr 1y agounless... you know
- eyelidlessness 1y agoTo be fair, this is a better example of booleans being a poor fit for modeling many problems. And it’s solvable without even addressing either issue (eg how this is modeled in the real world with multiple affirmatives).
- rictic 1y agoPrivate fields, unique symbols, there's many ways to do nominal typing in TypeScript, depending on what you want.
- eyelidlessness 1y agoI think that’s part of the problem: there’s no canonical idiom. The other part of the problem (IME) is that the biggest gap in nominal typing support is exactly what enum solves: nominal primitives. Yes, you can kinda get there with branding, but that’s a hack with a ton of footguns built in. And in many cases, you can box those values. But that can be an awful perf trade off in a hot loop, which is (again IME) often exactly where nominal primitive types would be incredibly helpful.
- nsonha 1y ago> enum has long been panned by most users). Same with namespace Why? Would you would rather do a smurf naming convention than having your consts, DTOs, events, errors and what not neatly organized under the name of the function that uses it?
- WorldMaker 1y agoYou don't need to do a smurf naming convention if everything is modules (especially ESM). TS Namespaces are a hack from the time when everything was global scoped, but ESM has been around since ES2015, is supported out of the box in all major browsers today, and is supported in Node (I recommend "type": "module" in package.json) and preferred/native in Deno and Bun.
- nsonha 1y agoI find it's rather annoying that I specifically made the point that namespace allows grouping things and you just "psst have you heard of ...modules"? Just create a new file for every group of thing? That's nice, do you create a new file for every function and all its options and error types?
- WorldMaker 1y agoYes, if that's the organization structure that makes the most sense for that project. Arguably that's the most common React organization pattern going a long way back whenever Components are functions you generally have one function per file, plus a bunch of extra types for options/error types.
- nsonha 1y agonot all code is a React component. And enforcing one component per file is just gonna encourage bloated components (because who likes heaps of tiny files?). I would not cite every front-end convention as an inspiration for sensible engineering.
- veidr 1y agoThis is exactly right, and the constructor parameter incompatibility is a big deal. The other two aren't nothing, either, even if enums are generally not the prevailing best practice in most cases. This is an interesting development, but it's not really "running TypeScript code" its "almost running TypeScript code". With alternative runtimes like Deno and Bun able to run real TypeScript code (and type check it, lint it, test it, etc) using a slightly watered-down, not-fully-compatible dialect of TypeScript, just so that it can run on Node without a build step, really isn't a very compelling argument. It'd be different if TypeScript announced "TypeScript will remove these features to work around Node's limitation — compatibility is more important", but they haven't. (And I wouldn't personally love it if they did. Deno and Bun are ahead of Node on several different axes, and other runtimes are coming, too — if Node can catch up, then great, but if it can't, then it should rightly be left behind.) There's still no real alternative to Node for many large frontend apps in production, but for a lot of other TypeScript use cases — build tooling, backend APIs, CLI apps, edge functions — modern TypeScript in the Deno/Bun style (ESM, full filename imports, run/typecheck/lint/test with no user-configured build step) has significant benefits. Both Deno and Bun have extensive — and necessary — backward compatibility shims to enable interoperability with what I've started calling "legacy Node JS/TS". You can use the Node APIs (but should explicitly import those things with "node:" in your import specifier. You can use NPM packages (even CommonJS ones, although Deno prohibits CommonJS in new code, a stricter line than Bun draws). I don't think using Deno and Bun is a huge bet on those specific (VC-backed) runtimes, either, because there is a shared vision of what "modern TypeScript" looks like, it works with both of those tools, and I think there will be multiple runtimes that support that vision for as long as TypeScript is relevant, even if both Deno and Bun were to go sideways. Whether Node itself will become one of those modern runtimes is an interesting question. This is a step in that direction, it looks like, but it's still an open question.
- koakuma-chan 1y agoWhich other runtimes are coming?
- veidr 1y agoI forget, and I was on my phone (and am still whooooooooo Friday niiiight!!!) but there are definitely at least two more in some stage of development (but we'll see if they actually ship to a prod-ready 1.0). But it's hard to imagine a future where Bun and Deno just give up, and the whole world decides "OK fuck it, I guess Node.js is the end of the line!" (Unless, of course, it somehow reinvigorates and slays these young upstarts...)