Node.js adds experimental support for TypeScript
github.com
github.com
Consider for example: `foo < bar & baz > ( x )`. In TypeScript 1.5 this parsed as (foo<bar) & (baz > (x)) because bar&baz wasn’t a valid type expression yet. When the type intersection operator was added, the parse changed to foo<(bar & baz)>(x) which desugared to foo(x). I realise I’m going back in time here but it’s a nice simple example.
If you want to continue to use new TypeScript features you are going to need to keep compiling to JS, or else keep your node version up to date. For people who like to stick on node LTS releases this may be an unacceptable compromise.
> 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 releases new features that we don't support or breaking changes, or users want to use the new shiny experimental feature, they can upgrade it separately. This ensures that users are not locked, but also provides support for a TypeScript version for the whole 3 years of the lifetime of Node.js release.
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. ;)
It won't, but in such a scenario, typescript would only be a type checker, wich is a entirely different endeavor than running typescript.
It's still just (early in the process) Stage 1, but the majority of Typescript's type syntax, for the purposes of type stripping (not type checking), is attempting to be somewhat standardized: https://github.com/tc39/proposal-type-annotations
When TypeScript added const declarations, they added it as `as const` so a type stripping could have still worked depending on how loosely it is implemented.
I think there is a world where type stripping exists (which the TS team has been in favor of) and the TS team might consider how it affects type stripping in future language design. For example, the `satisfies` keyword could have also been added by piggy-backing on the `as` keyword, like:
const foo = { bar: 1 } as subtype of Foo
(I think not using `as` is a better fit semantically but this could be a trade-off to make for better type stripping backwards compatibility)Updating node is much more fraught than updating TypeScript. For example, it may break any native code modules. That’s why users are directed to use the LTS and not the most recent release, so that there’s enough time for libraries to add support for the new version.
On the other hand, I usually adopt a new TypeScript version as soon as it comes out.
("Boring" in this context is a compliment, by the way)
EDIT: Though reading other comments, it seems like you can update the typescript stripper independent of node? That makes this moot anyway
For production use, I'd still put my TS files through a build pipeline as normal
With a couple exceptions (like enums), you can strip the types out of TypeScript and end up with valid JS. What you could do is stabilize the grammar, and release new versions of TypeScript using the same grammar. Maybe you need a flag to use LTS grammar in your tsconfig.json file.
Apart from a clueless engineer attempts them, it's been working out fine to pretend they don't exist.
There was no perfect solution available, so a tradeoff was necessary. You can disagree with this particular tradeoff, but had they gone another way some people would disagree with that as well. To be a mistake there would have had to have been an option available that was clearly better at the time.
Anyway, the idea that TS 5 should be backwards compatible with TS 1 is probably a bad one. Personally, I think packages with wide usage break backwards compatibility far too easily -- it puts everyone who uses it on an upgrade treadmill, so it should be done very judiciously. But even I wouldn't argue that TS 1 should have been its final form.
I think Rust made the really smart move of putting :: before any type parameters for functions. Go made the good move of using square brackets for type parameters.
We really need five sets: grouping, arrays/indexing, records, type parameters, and compound statements. Curly braces {} are also overloaded in JS for records and compound statements, leading to x => {} and x => ({}) meaning different things.
Square brackets wouldn't work for parametric functions because f[T](x) already means get the element at index T and call it.
You could argue that it was a C++ mistake. It makes parsing harder, but otherwise seems to work as expected, so I don't consider it a mistake, but you could at least argue that way.
But regardless if it was a mistake in C++, it's now a complete standard, used in C++, Java, C#, and other languages to denote type parameters.
I would argue that it would have been a mistake to break that standard. What would you have used, and in what way would that have been enough better to compensate for the increased difficulty in understanding TypeScript generics for users of almost every other popular language?
We find Typescript much easier to upgrade than Node. New Node versions change performance characteristics of the app at runtime, and sometimes regress complex features like async hooks or have memory leaks. We tend to have multi-week rollout plans for new Node versions with side-by-side deploys to check metrics.
Typescript on the other hand someone can upgrade in a single PR, and once you get the types to check, you’re done and you merge. We just got to the latest TS version last week.
Unlike Python typing it's not only type erasure: enums, namespaces, decorators, access modifiers, helper functions and so on need to be transformed into their JavaScript equivalent.
To me beyond v4.4 or so, when it started being possible to create crazy recursive dependent types (the syntax was there since ~4.1 - it's just that the compiler complained), there weren't a lot of groundbreaking new features being added, so unless an external library requires a specific TS version to parse its type declarations, it doesn't change much.
Some edge-cases involving those have bugfixes and ergonomy improvents I've run into on 5.x.
That being said I regret every use of `infer` in application code.
It's interesting, though, that this approach in Python has led to several (4?) different popular type checkers, which AFAIK all use the same type hint syntax but apply different semantics. However for JavaScript, TypeScript seems to have become the one-and-only popular type checker.
In Python, I've even heard of people writing types in source code but never checking them, essentially using type hints as a more convenient syntax for comments. Support for ignoring types in Node.js would make that approach possible in JavaScript as well.
With normal Javascript and typescript, you can't minify property names, so `foo.bar.doSomethingVeryComplicated()` can only be turned into `a.bar.doSomethingVeryComplicated()`, not `a.b.c()`, like with Closure. This is because objects can be indexed by strings. Something like `foo.bar[function]()` is perfectly valid JS, where the value of `function` might come from the user.
A minifier can't guarantee that such expressions won't be used, so it cannot optimize property accesses. Because Closure was a type checker and a minifier at the same time, it could minify the properties declared as private, while leaving the public ones intact.
There was: Anders Hejlsberg and Lars Bak: TypeScript, JavaScript, and Dart https://www.youtube.com/watch?v=5AqbCQuK0gM (2013).
Summary: https://g.co/gemini/share/a60c3897bae1 / https://archive.is/qJ1wA
Both choices are reasonable ones to make. Flow has some really cool stuff, and works great for a lot of people.
There’s no denying, though, that there’s TS has done something right (even if you personally dislike it)
Note that there's IDEs that'll use type hints to improve autocomplete and the like too, so even when not checking types it can make sense to add them in some places.
The biggest pain point of using JSDoc at least for me was the import syntax, this has changed since Typescript 5.5, and it's now not an issue anymore.
In a world where ES modules are natively supported everywhere it’s a joy to have a project “just work” with zero build steps. It’s not worth it in a large project where you’re already using five other plugins in your build script anyway but for small projects it’s a breath of fresh air.
I use this approach professionally in teams with many developers, and it works better for us than native TS. Honestly give it a try, I was skeptical at first.
It's fine on toy projects, and somewhat I would say, for 99% of users that don't even know what a mapped or intersection type is.
JSDoc is indeed fine on toy project, or in fact any project (even prod-ready ones) that doesn't warrant the trouble of adding NPM packages and transpilation steps.
Although they are rare, those type of small, feature-complete codebases do exists.
Node.JS isn't the only JS runtime. You'll still have to compile TS to JS for browsers until all the browsers can run TS directly. Although some bundlers already do that by using a non-official compiler, like SWC (the one Node's trying out for this feature).
> In Python, I've even heard of people writing types in source code but never checking them, essentially using type hints as a more convenient syntax for comments.
It's not just comments. It's also, like the name "type hint" suggests, a hint for your IDE to display better autocomplete options.
Ah yes, autocomplete is another benefit of machine-readable type hints. OTOH there's an argument that another IDE feature, informational pop-ups, would be better if they paid more attention to comments and less to type hints:
https://discuss.python.org/t/a-more-useful-and-less-divisive...
I think this should be part of the language spec.
E: I thought it was JSDoc proposal. Ignore the comment.
They just can't have browsers doing the actual type checking because there isn't a specification for how to do that, and writing one would be extremely complicated, and I'm not sure what the point would be anyway.
This is my main approach. Type hints are wonderful for keeping code legible/sane without going into full static type enforcement which can become cumbersome for rapid development.
But if I were putting in type hints like this, I'd still definitely want them to be statically checked. Its better to have no types at all than wrong types.
I agree - but the type systems of both Python and TypeScript are unsound, so all type hints can potentially be wrong. That's one reason why I still mostly use untyped Python - I don't think it's worth the effort of writing type annotations if they're just going to sit there and tell lies.
Or maybe the unsoundness is just a theoretical issue - are incorrect type hints much of a problem in practice?
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```
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 : int”
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, so you want to avoid things like p:”prime number”
I personally would very much prefer if NPM modules that have their original code in TS and are currently transpiling would stop shipping dist/.cjs so I unambiguously know where to put my debugger/console.log statements. And it would probably be very tempting to NPM contributors to not have to bother with a build step anymore.
But won't this start a ripple effect through NPM where everyone will start to assume very quickly 'everyone accepts TS files' - it only takes one of your dependencies for this effect to ripple through? It seems to me that nodejs can't move this outside an opt-in-experimental-flag without the whole community implicitly expecting all consumers to accept TS files before you know it. And if they do, it will be just months before Firefox and Safari will be force to accept it too, so all JS compilers will have to discard TS type annotations
Which I would personally be happy with - we're building transcompiling steps into NPM modules that convert the ts code into js and d.ts just to support some hypothetical JS user even though we're using TS on the including side. But if node accepts .ts files we could just remove those transpiling steps without ever noticing it... so what's stopping NPM publishers from publishing js/d.ts files without noticing they broke anything?
Essentially what it does is allow you to upload your typescript code without a build step so when other devs install it they can see the source code of the module in it's original typescript instead of transpiled JavaScript.
Apparently you can only view the uncompiled source code in deno since it natively supports typescript.
My bad
For a new thing I was writing from scratch, yeah, I might just ship typescript and not bother transpiling.
[edit: Apparently not. TS is only for top-level things, not libraries in node_modules according to the sibling comment from satanacchio who I believe is the author of the PR that added TS support and a member of the Node.js Technical Steering Committee]
Besides, it's already going through one transpilation step to go from TS to ESM, so adding a second one for CJS really isn't that much hassle.
I think if node.js had made require() work with ESM, I could probably drop CJS. But since that's probably never going to happen, I'm just going to continue shipping both versions for old projects and not worry about it.
I'd rather kill ESM. And it's not fully supported in Node. It doesn't work in the REPL.
That would be a huge win. Right now in Python, great tools like pydantic exist because Python can introspect said types, and generate checks out of them.
This mean you can define simple types, and get:
- type checking - run time data check - api generation - api document generation
Out of a single, standard notation.
Right now in JS, things like zod have to do:
const mySchema = z.string();
Which is basically reinventing what typescript is already doing.For those unfamiliar:
`z.string()` effectively converts `mySchema` into a functional schema capable of parsing and validation.
For example:
`mySchema.parse("some data")` returns successfully.
`mySchema.parse(321)` throws an exception.
I've used it in places where you need runtime validation and in process verification - it works pretty well for that and you can extract the types from it via :
const A = z.string(); type A = z.infer<typeof A>; // string
Meaning if you define your types in zod first, and infer their types from that you get compile and runtime type checking.
---
It a bit of an overkill for nimble and fast code bases though - but works wonders for situations where in process proofing needs to be done, and in all honesty it isn't that big of a task to do this.
Well of course it offers more, or you wouldn't be installing a library.
The problem is that even when you're expressing normal Typescript types, you have to use entirely different syntax. It's good that you can usually avoid double-definition, but it's still a big barrier that shouldn't be necessary.
Having said that, TypeScript allows plugins, these are very rarely used as they augment the language by introducing other features that are transformed into the resulting JavaScript files. One plugin that relates to your suggestion of run time types is called Typia, it permits you to use your TypeScript type signatures at runtime with guards like `assert<MyType>(myValue)` where it intercepts the function call to construct an exhaustive if statement in the transpiled JavaScript checking the nature of the passed variable.
So while I don't see it being a part of the language in the next four to six years, there are at least libraries out there already that allow you to do it today.
We need a type system that is actually sound and TS is intentionally unsound. We need a type system that doesn't allow bad coding practices like TS does. We need a type system that enforces program design that allows programs to be fast. We need a Hindley Milner type system.
If you want a module to be typed, add a `"use type"`. This should disallow bad parts of the language like type coercion. It should disallow things that hurt performance like changing object shape/value type or making arrays of random collections of stuff. Incoming data from untyped modules would either coerce or throw errors if coercion can't be done at which point the compiler can deeply-optimize the typed code because it would have far stronger type guarantees and wouldn't have a risk of bailing out.
it blows my mind weekly how ergonomic and flexible typescript’s type system is. it allows me to write great apis for my team mates.
is it possible for the type checker to end up in an infinite loop or for a junior developer to abuse “as”? absolutely, but it doesn’t really matter in practice.
i wouldn’t want to run typescript in rockets or submarines tho!
TS types are IGNORED by the JIT to generate SLOW code.
All the features that make Typescript more ergonomic for devs also allow it to generate slower JS code. AssemblyScript tries to be TS for WASM and it doesn't support huge swaths of TS because they output unusably slow garbage.
I also suspect that more than a few Ocaml ergonomic issues are due to nominal typing. StandardML's structural typing and inference give an experience very similar to TS, but without the major soundness issues (though it must be noted that ANY generics in JS will be slow unless the compiler is creating multiple function variants).
type A = { value: number; }
function test(a: A) { a.value = 3; }
function main() {
const a: Readonly<A> = { value: 1 };
// a.value = 2; <= this errors out
test(a); // this doesn't error out
console.log(a); // shows 3
}Does TS help you keep your functions monomorphic so they'll get optimized by the JIT? nope
Does TS keep your object shape from changing so it will get optimized by the JIT? it actively does the opposite giving TONS of tools that allow you to add, remove, modify, and otherwise mess up your objects and guarantee your code will never optimize beyond the basic bytecode (making it one or two orders of magnitude more slow than it could otherwise be).
TS doesn't do anything to prevent or even discourage these kinds of bad decisions. They "type soup" many projects fall into is another symptom of this. The big reason the types become such a mess is because the underlying design is a mess. Instead of telling programmers "fix your mess", TS just releases even more features so you can type the terrible code without fixing it.
If only projects like Bun/Deno/Node added runtime support for ReScript instead of TypeScript, collectively as the web-tooling industry, we'd be in a better place. But you can't win against the MS's marketing budget.
Also in hindsight, ReScript diverged away from OCaml, but the ReScript development team could have gone further by creating a runtime for ReScript. Then again I don't blame them - they are polishing the dev experience of ReScript and React.
This is the decade of writing shiny new runtimes - I hope somebody writes a ReScript runtime. Imageine ReScript, Core, rescript-webapi, typechecker, re-analyze, plus a bundler minifier etc baked into the runtime like Bun. Sounds like an interesting value proposition. Fingers crossed.
However, in TS other type information is erased at compile time. So if you write
type Foo = "a" | "b";
the runtime code will see that just as a plain string.The parent commenter was talking about a way for nodejs to provide, via an API, the content of type annotations on fields/functions/variables like in python.
However, in python the type annotations are a property of the object at run time, whereas they are completely stripped before execution for typescript.
So I'm not sure how it would work except by changing the typescript philosophy of "not changing runtime execution"
Meanwhile, I can’t configure node to not require extensions on import, nor have tsc configured to automatically add .js extensions to its compiled output, without adding on a bundler… although native TypeScript support would remedy this nit quite a bit, I can’t imagine the user experience (or performance) to match Bun’s when it reaches stable.
foo could mean foo/index.js, foo.js at the minimum. So you have 2x the lookups. Oh no, wait we also potentially have mjs, cjs, jsx, ts and tsx.
So 12 times the stat checking for each import.
Well except for Deno...
Jokes apart, Zig is moving forward a lot which is why it's not 1.0 yet, but it doesn't mean you can't write safe and performant applications right now.
Zig is also a rather simple and straightforward language (like C) and has powerful compile-time code generation (like C macros, but without the awful preprocessor).
If you use frameworks written for node memory usage is very high and performance is meh.
If you use frameworks written for bun they smoke anything on node.
I'd definitely move over, just to get rid of the whole TypeScript / cjs / esm crap, but:
1. frontend support is poor (next.js / solid.js - I can't run anything fully on bun)
3. I still need to rewrite my backend app from a node.js framework to a bun one
4. for backend development the javascript ecosystem is losing the crown: if I wanted something safe I'd just write it in Rust (TS allows any random developer to write crap with any in it and it validates), if I'm doing something AI related I'd probably need python anyway and fastapi is not half bad
However, the node:crypto module still doesn't work 100%. So, I can't use it yet.
It seems to be the default now:
$echo 'console.log("test")' > t.ts
$ tsc t.ts
$ ls
t.js t.ts
$ node t.js
testI guess we all just wanted java with JIT, more feature rich type system and gradual typing. Also for all the shortcomings of npm ecosystem, it is a lot less daunting and more fun to be using libraries in this ecosystem.
And surprisingly even though rust is on a different end of the language spectrum but yet it offers a similar feel.
Edit: JIT was not the right terminology to use. I lazily wrote JIT. Apologies. What I meant to convey was the difference in startup times and run time between running something in JVM and V8. Java feels heavy but in javascript ecosystem it feels so nimble.
Java was literally the thing that made the term "JIT" popular, so I really don't know what you were going for here.
Also I just can't see how Typescript is in any way "closer" to Java - it's incredibly different IMHO. The only thing they have in common is probably the "Javascript" misnomer and the fact both support imperative programming, but that's it.
One thing I miss that java has is runtime reflection of types though. Typescript's ecosystem has a million different ways to get around that and they're all a bit ugly imo.
Java has JIT. How is TypeSript type system feature-richer than the Java one?
https://www.typescriptlang.org/docs/handbook/2/template-lite... alone puts TS over anything that Java has.
Some examples of TypeScript power:
- SQL database in TypeScript types: https://github.com/codemix/ts-sql
- Statically typed raw SQL queries: https://github.com/andywer/squid?tab=readme-ov-file#tag-func...
- (Someone fill in your TS hackery for me)
Utility types, like Partial<T>, are basically impossible to represent in Java except with almost-duplicated classes.
I also want compiler/type checker niceties like exhaustive pattern matching.
Oh god no. What an abomination.
Greater than 95% of the incompetence in JavaScript comes from two camps. The first of those are people who absolutely cannot program at all. The second of those are Java developers who were taught Java in school and it’s all they can do, so everything must look like Java.
The result of both tribes is pretending to do something they cannot do on their own. When you’re a pretender vanity becomes excessively important because everything is superficial, so you get layers of shit you don’t need that they cannot live without. Any attempts slice off the unnecessary bullshit always results in hyper emotional distress because people feel threatened when exposed. That right there is why I will never write JavaScript for employment ever again.
With TS you can prototype with JS and only after you know what you are looking for you can start to add types to find bugs and edge cases and want to get nice code completions for your stuff.
God I wish they’d just integrate something lightweight like npm into JDK.
It is beyond me why you have to install third-party heavy weight tool just to manage dependencies.
AKA dynamic typing. Unless it's 100% static, it's dynamic
Elixir's new type system does much better here, as it determines whether a function actually guards for the right type at runtime ("strong arrows") and propagates the guarantees, or lack thereof, accordingly.
In Typescript you have far more freedom, and all the benefits of strong types.
Maybe this means I don't always have to install esbuild to strip types - very excited how this will make writing scripts in TypeScript that much easier to use. I lately have been prefering Python for one off scripts, but I do think personally TypeScript > Python wrt types. And larger scripts really benefit from types especially when looking at them again after a few months.
You cannot run tsx from a non-project cwd if you’re using tsconfig/paths.
And personally I find its maintainers relatively unpleasant to message with. Leaves “you’re plebs” aftertaste most of the times.
> Node.js standard library requires additional hassle before using
I read the hassle as having to setup Node runtime in advance, but zx requires npm to install so I'm not sure.
Node is copying many of these features to varying degrees of success. But Deno is evolving, too.
Kidding aside: You should really take an hour and check out the manual and std lib (https://jsr.io/@std). I was surprised how far Deno has come. A lot of pretty useful stuff you would otherwise need tons of NPM modules for.
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?
Typescript seemed like a good option but was just another bolt on, I am not sure what value you gain by using Typescript over Golang, you have nice defined types which is great but it does not solve other issues with the language that are resolved in golang (also solved in deno).
One large benefit of using node over golang is the speed of prototyping something which I think having to use type script largely negates, so I can not really decide if this is a good step forwards or is making node loose some qualities that made it a good choice in other ways.
I've never used Django. Express seems a lot nicer.
In the company I worked at we were fairly small and did not have huge applications running on node, so it made that journey easier
That's definitely a potential issue - JavaScript is the fundamental standard, not JQuery and not TypeScript. Certainly there are situations where maximum forward-compatibility is important (learning resources are a good example) and for those, vanilla JavaScript is the best choice.
All of the old resources that relied on JQuery are now hopelessly outdated, whereas the contemporary ones that used plain JavaScript are as valid now as when they were written. I'm sure the same will be true of TypeScript vs JavaScript when the next big thing comes along.
True, but on the other hand, almost any JS code snippet written 20 years ago has better and more elegant alternatives today. APIs evolve all the time.
jQuery was so popular because writing anymore than a few lines of vanilla JavaScript was an *awful* experience due to all differences in browsers.
When things eventually standardized-ish and jQuery became unnecessary, other libraries/ecosystems popped up (e.g. React/JSX) to make writing webapps easier because writing anymore than a few lines of vanilla JavaScript was still an *awful* experience.
When webapps grew in size and scope, other "transpiled" languages popped up (e.g. TypeScript) because writing anymore than a few lines of vanilla JavaScript is *still an awful* experience.
We're stuck with JavaScript due to past decisions, but let's not pretend it's actually a good tool. If it were we wouldn't need 50,000 tools/frameworks/transpiled languages to hide how terrible it is.
I wonder bun and deno support for typescript played a big role here :)
I’m also not sure the features will eventually “tickle down”. I’m not sure NPM wants to adopt the advantages PNPM gives you as an example, and it’s probably a good thing too considering the basis of NPM is just a really solid system to build on top of which it wouldn’t be if it was very opinionated. One of the big issues Node has today is that it was very opinionated with CommonJS, which made sense at the time, but is a ginormous pain in the butt in the modern world. Though the blame is obviously not with Node alone.
How many days have you spent on webpack config? Or the package.json type property? Or yarn/pnpm/etc particulars?
I have spent too many.
Bun is quite nice.
node has a built in test runner now
I'm even willing to forgive all the mess that CJS vs. ESM is if they manage to pull this off.
I hope this sees widespread adoption/usage, which might finally cause some movement to integrate TS into ecmascript after all. Some dynamically-typed language fanatics (which are, in my opinion, completely detached from the reality that static types are what the vast majority of devs want) still have an iron grip on TC39, this might be the start of their end. And good riddance.
[citation needed]
The sad thing about the tech sector is that you can be right about something and yet still lose the hype-wagon popularity contest. Then your competitor copies your original idea... The exact same idea which they had previously claimed was inferior.
It seems that the idea was inferior purely on the basis that it wasn't their idea. As soon as they've appropriated the idea, suddenly it's the best idea in the world.
So many runtimes and tools are integrating TypeScript now, and with multiple implementations, that a real standard is necessary. It'll be much harder to evolve TypeScript because it'll have to stay backwards compatible, but it's grown to that point now, imo.
Years and years ago. Now it's whatever the compiler does.
Which to be fair, is evolving quite rapidly.
The type checker is immensely complex and should be left out so that other type checkers can be developed, e.g. similar to how it's for Python today.
I do think that the semantics should be standardized too, otherwise you have non-interoperable types. The goal should be that you can use two libraries together without having to make sure they use the same type-checker.
What TC39 needs is a type system that limits what you can do to things that are sound, performant, and good practice. TS is the exact opposite of this.
A lot of effort and money has been invested into JS engines. I wonder if making a TS native engine (which nobody has made yet) from scratch might make more sense than adapting JS engines to run TS.
To take one extreme example, a library I work on includes an API for calling a JSON RPC server. Instead of manually implementing each call, we use a proxy object that converts any method call on it to a JSON RPC call. Then layer on types so given an RPC object you know every method on it and have typed input params and output. This means you can have any number of methods without increasing your bundle size, because all the types disappear at runtime. It also means you can add your own methods if you’re talking to a server that implements custom ones by just defining types. If you shipped this to the browser with the types then it’d be a much bigger bundle than without them.
yeah, the ecosystem sucks, but rewarding the system incentivized to co-opt the system will actually make things worse in the long run, not better.
for example, internet explorer failed why?
IE failed because it was a horrible browser that didn’t evolve for years and was incompatible with major web standard developments. Nothing to do with typescript, an open source, best in class type system and type checker.
If you need JS syntax features that Node.js doesn't support you can use tsc, babel, etc.
Because obviously unsupported features are unsupported, whether JS or TS.
This is only 'half-assed' anyway, TS will only emulate new language features on older JS target version, but not any Javascript runtime features (like new Object methods). For the latter you will still need a separate polyfill solution.
I understand that built in TS support is very nice as provided by Bun. But I feel doing this in Node is going to take a long time.
> During the transpilation process, no type checking is performed, and types are discarded
Which makes perfect sense to start out with; as typechecking with tsc is rather slow and can easily be delegated to the consumer.
(I use Deno, but also use some npms.)
In which case wouldn't V8 support TS directly without needing to transpile?
> There is a TC39 proposal for type annotations
Which links to https://github.com/tc39/proposal-type-annotations
It is a long ways off though.
that would be a lot of work
I would rather see new WASM features instead
type: module requires file extensions and does not support importing folders like most people are used to so it will not be compatible with most existing Typescript code.
Will it transform esm import syntax into require statements?
I'd prefer it break existing code to enforce correctness
There are about 100 messages in the comments on the linked PR all about the import extensions compatibility/consequences :)
There's a "roadmap doc" here https://github.com/nodejs/loaders/issues/217 that states "No .js extension for .ts files."
> I'd prefer it break existing code to enforce correctness
That seems to be the goal and intent (from TS and Node team too https://github.com/nodejs/node/pull/53725#issuecomment-22301... )
> Will it transform esm import syntax into require statements?
IIUC no
see the docs about which module system Node picks for the loaded files https://github.com/nodejs/node/blob/main/doc/api/typescript.... ("Node.js will not convert from one module system to another")
The authors trick you with reasonable examples on https://www.typescriptlang.org, but in the wild, you have these ridiculous codebases that couldn't control themselves and they have this insane ratio of multiple declaration files to actual source files and you have to ask yourself, "Are you writing software to get something actually done, or do you just like write type definitions?"
Even people who write in C++ don't go to the lengths that TypeScript users do. It's super weird and cult-like.
There are some type libraries that parse GraphQL queries and CSS selectors. They’re crazy to look at but they’re hugely helpful.
In C# you can't work with optional generics because an optional reference type is different from an optional value type.
C#s poor type-inference often requires you to type out types thrice. You can't declare constants or class members with type-inferrence.
The only way to define sum-types (A | B | C) is through intefaces and I'm pretty sure they can't be sealed. Defining product-types (A & B & C) is impossible.
Eventuall they add the feature something else has, and then everyone uses it again instead of the other thing.
https://github.com/tc39/proposal-type-annotations
So maybe we'll have support in another five years
... Or maybe we'll have "Support in another five years" in five years, who knows
Enums are one of the very few things in typescript that seem to not have turned out that well, but it's relatively easy to work without them with string-literable types and such, derived from some const in case they're also needed at runtime.