Ein Blog

Matt Pocock hat frohe Kunde verbreitet und angekündigt, dass in der nächsten Node-Version das “Strip Types” nicht mehr hinter einem Flag ist. Das heißt, dass Node.js bald nativ TypeScript ausführen kann. Die Types werden einfach rausgenommen und alles wie JS interpretiert. D.h. kein TS-Compiler-Check und keine Runtime-Checks. Ersteres ist quasi nicht möglich, ohne TSC in Node.js zu integrieren. Das ist etwas doof, weil TypeScript keine Spec hat, sondern nur eine Referenzimplementierung. Runtime-Checks haben dasselbe Problen und manche Typen sind in TS so komplex, dass allein das Type-Checken bspw. eines Funktionsparameters mehr Zeit in Anspruch nehmen kann, als die eigentliche Funktion. Insoweit gut, dass beides kein Teil hiervon ist.

Was bei ihm aber nicht steht und was durchaus wichtig ist:

Imports müssen auf .ts enden

Das geht gegen die bisherige Vorgehensweise von Node-Devs bei JS (die haben üblicherweise die Erweiterung weggelassen) und gegen die Empfehlung von TypeScript selbst (.js verwenden, auch, wenn es eine .ts-Datei ist). Die Empfehlung der TS-Leute ist aligned mit dem, was tatsächlich iim ESM-Standard steht. TypeScript hat bisher auch darauf verzichtet, Import-Pfade umzuschreiben.

Bun hat hierfür einen Resolution-Algorithmus, der bei einem Import von ./foo von ./foo.js über ./foo.ts und ./foo.mts etc alles absucht. Hier kann es zu unerwartetem Verhalten kommen, wenn eine ./foo.js und eine ./foo.ts existiert. Aber hier ist es immerhin möglich, seine Imports zu lassen, wie sie sind. tsx (ein Node-Wrapper, der ähnlich wie die jetzige Implementierung von Node-Type-Stripping funktioniert) kann das auch.

Path-Aliase

Node möchte hier jetzt .ts in Imports. TypeScript hat in den sauren Apfel gebissen und 2 Compiler-Flags dafür eingebaut: allowImportingTsExtensions und rewriteRelativeImportExtensions. Ersteres erlaubt .ts in imports. Letzteres macht nach dem Kompilieren ein .js aus .ts. Das ist praktisch, um nach dem Kompilieren noch validen JS-Code zu haben, denn sonst würde dort in den Imports js .ts stehen.

Was nicht umgeschrieben wird, sind nicht-relative imports. D. h. alle Imports, die nicht mit ./ oder ../ beginnen, bleiben so.

Manche Projekte haben einen "@/*"-Path-Alias, der auf das Root-Verzeichnis des Projekts zeigt. Falls ihr das habt, könnt ihr also nicht auf Node.js mit TS-Direktausführung migrieren. Dafür braucht man dann noch irgendeinen extra-loader wie bisher auch. Oder ihr benutzt Bun oder tsx. Damit das funktioniert, muss Node.js die tsconfig.json lesen und verarbeiten. Ich denke aktuell, dass das zu komplex wär, dass das Node-Team das umsetzt.

Bisher wird es auch dabei bleiben.

Also insgesamt leider noch ein ferner Traum, dass man TS für bestehende Projekte einfach mit Node.js direkt ausführen kann. Dafür braucht man immer noch einen modifizierten Loader, bun, Deno, ts-node oder tsx.