Node FINALLY Supports TypeScript
Summary
TLDRThe script discusses the long-awaited support for TypeScript in Node.js, a feature that has been absent since Node's inception in 2009. It highlights the emergence of alternatives like Dino and Bun, which embraced TypeScript early on. The speaker delves into the complexities of integrating TypeScript, emphasizing the distinction between type checking and transpilation. The introduction of a new Node.js flag that enables type stripping—removing TypeScript syntax without type checking—is explored. The script also touches on the TC39 proposal for type annotations in vanilla JavaScript and the use of SWC (a Rust-based tool) for implementing this feature, aiming to streamline the JavaScript ecosystem and reduce the need for external dependencies.
Takeaways
- 🕰️ Node.js was released in 2009, but it still doesn't natively support TypeScript, which has become the language of choice for the JavaScript ecosystem.
- 🏆 TypeScript has won the debate over other type systems like Flow, solidifying its position as the preferred choice for JavaScript projects.
- 🔄 Supporting TypeScript is complex because it can mean different things to different people, ranging from type checking to running TypeScript code directly.
- 📝 The TC39 proposal for type annotations aims to integrate TypeScript-like syntax into vanilla JavaScript without the need for transpilation.
- 🛠️ The goal of the TC39 proposal is to allow developers to run TypeScript, Flow, and other static typing supersets of JavaScript in the browser without modification.
- 🚫 Previous attempts to enforce types in JavaScript, like the V8 team's 'strong mode' experiment, resulted in performance issues and were eventually abandoned.
- 🛑 The new Node.js flag for TypeScript is not about type checking but about stripping types and running the resulting JavaScript code.
- 🔧 Node.js will use the 'swc' (Scalable Web Compiler) package for type stripping, leveraging its efficiency and small footprint compared to other solutions.
- 🌐 The use of WebAssembly for 'swc' allows it to run across all platforms without the need for platform-specific binaries, reducing the size and complexity of Node.js.
- 📜 The 'Amaro' package, a wrapper around 'swc', will handle the type stripping process in Node.js, making it easier to execute TypeScript files without external dependencies.
- 📝 Node.js will enforce the use of file extensions and module syntax, requiring developers to explicitly use either CommonJS or ES module formats.
Q & A
Why is the support for TypeScript in Node.js significant?
-Support for TypeScript in Node.js is significant because TypeScript has become the language of choice for the JavaScript ecosystem, especially for building tools and projects. Node's support for TypeScript without the need for external dependencies or loaders can streamline development and move the ecosystem forward.
What are the two main functions of the TypeScript compiler?
-The TypeScript compiler has two main functions: type checking, which verifies the correctness of the types used in the code, and transpilation, which converts TypeScript code into JavaScript code.
Why was the TC39 proposal for type annotations introduced?
-The TC39 proposal for type annotations was introduced to add type annotations to the vanilla JavaScript specification in a way that allows developers to run programs written in TypeScript, Flow, and other static typing supersets of JavaScript without the need for transpilation.
What is the main goal of the TC39 proposal regarding type annotations?
-The main goal of the TC39 proposal is to enable developers to run TypeScript, Flow, and other statically typed code in the browser without any need for transpilation, by treating type annotations as a comment syntax rather than a type-checked strict language.
What is the difference between type checking and transpilation in the context of TypeScript?
-Type checking is the process of verifying the correctness of the types used in the code, ensuring there are no type errors. Transpilation is the process of converting TypeScript code, which may include type annotations, into plain JavaScript code that can be executed in a JavaScript runtime environment.
Why did the V8 team experiment with a 'strong mode' for JavaScript?
-The V8 team experimented with a 'strong mode' for JavaScript to enforce types and improve site performance. However, the experiment was canceled due to the non-negligible slowdown it caused, indicating that enforcing types can sometimes lead to more performance problems than it resolves.
What is the role of the 'swc' package in the context of Node.js and TypeScript?
-The 'swc' package, specifically the 'swc-wasm-typescript' package, is used by Node.js for type stripping. It is a Rust-based platform for the web that provides a set of compilation tools to convert TypeScript code into JavaScript code without performing type checking.
What is the advantage of using WebAssembly (WASM) for the 'swc-wasm-typescript' package?
-Using WebAssembly for the 'swc-wasm-typescript' package allows it to run in any environment supported by Node.js without the need for shipping multiple native binaries for different platforms, thus reducing the overall size and complexity of the package.
Why is the 'Amaro' package used in Node.js for type stripping?
-The 'Amaro' package is a wrapper around 'swc-wasm-typescript' and is used for type stripping in Node.js. It allows for the easy integration of the 'swc' transpiler within Node.js, providing a more streamlined and efficient way to handle TypeScript files.
What is the significance of file extensions in the new Node.js TypeScript support?
-File extensions are mandatory for TypeScript files in Node.js to ensure proper module resolution and to avoid conflicts with existing JavaScript files. This is part of Node.js's commitment to maintaining backward compatibility and clarity in module systems.
How does Node.js differentiate between CommonJS and ES module syntax when dealing with TypeScript files?
-Node.js will not automatically convert between CommonJS and ES module syntax. Developers must explicitly use the appropriate import and export syntax for ES modules or require and module.exports for CommonJS modules within their TypeScript files.
Outlines
📚 The Evolution of Node and TypeScript Support
The script discusses the history of Node.js, which was released in 2009 and still lacks native TypeScript support. It contrasts Node with newer alternatives like Dino and Bun, which have embraced TypeScript early on. The speaker emphasizes the dominance of TypeScript in the JavaScript ecosystem, not just for web applications but also for building tools around Node. The script introduces a new flag in Node that addresses the TypeScript support issue and mentions the tc39 proposal for type annotations in vanilla JavaScript, aiming to allow running TypeScript and other supersets without transpilation.
🔧 TypeScript's Role in Tooling and the tc39 Proposal
This paragraph delves into the complexities of supporting TypeScript in Node.js, highlighting the different interpretations of 'support.' It explains the two functions of the TypeScript compiler: type checking and transpilation to JavaScript. The speaker discusses the tc39 proposal's goal to integrate type annotations into JavaScript without enforcing them, allowing developers to run TypeScript code in browsers natively. The proposal aims to reduce the friction caused by custom syntax in JavaScript forks and to avoid syntax conflicts with tc39.
🛠️ Node's New Flag for TypeScript and the Importance of Transpilation
The script introduces a new flag in Node that enables stripping types from TypeScript, allowing the execution of TypeScript files as JavaScript without type checking. It explains the motivation behind this feature, emphasizing the community's demand for running TypeScript natively in Node. The speaker also touches on the technical aspects of type stripping, using the swc (Scalable Web Compiler) project, a Rust-based tool for efficient transpilation. The adoption of swc's WebAssembly TypeScript package is highlighted for its cross-platform capabilities and smaller size compared to native binaries.
🌐 The Future of TypeScript in Node and the Amo Package
The final paragraph outlines the future possibilities for TypeScript in Node.js, with the introduction of the Amo package, a wrapper around swc's WebAssembly TypeScript for type stripping. It discusses the benefits of this approach, including reducing the need for multiple binaries and the potential for separate upgrades from Node itself. The script also addresses the requirement for file extensions in import statements for TypeScript files and the ecosystem's efforts to integrate TypeScript support responsibly and effectively.
Mindmap
Keywords
💡Node.js
💡TypeScript
💡Deno and Bun
💡Type Annotations
💡TC39 Proposal
💡Transpilation
💡TypeScript Compiler
💡SWC (Speedy Web Compiler)
💡Enums
💡Type Stripping
💡ES Modules
Highlights
Node.js was released in 2009 but still doesn't natively support TypeScript.
Alternatives to Node like Dino and Bun have embraced TypeScript earlier in their development.
TypeScript has become the language of choice for the JavaScript ecosystem.
Supporting TypeScript varies from type checking to running TypeScript code directly.
Different TS config setups can result in different code outcomes.
Node's new flag aims to address TypeScript support without enforcing type checks.
TC39 proposal for type annotations seeks to integrate TypeScript-like syntax into vanilla JavaScript.
The goal is to allow running TypeScript, Flow, and other supersets of JavaScript without transpilation.
TypeScript's syntax, such as colons for type annotations, is not valid in standard JavaScript.
Efforts to enforce types in JavaScript have resulted in performance issues.
The distinction between TypeScript's type checking and transpilation is crucial for understanding the language's capabilities.
TypeScript files can be transpiled into JavaScript without type checking using tools like TSC.
Node's new feature will strip TypeScript types during transpilation, allowing direct execution of TypeScript files.
SWC, a Rust-based tool, is used for the type stripping process in Node.
SWC's WASM support allows it to run on any platform without native binaries, reducing the size of Node.
Node's strict requirement for file extensions and module syntax aims to maintain compatibility and clarity.
The introduction of type stripping in Node is a significant step towards supporting modern JavaScript practices.
The ecosystem's evolution shows a continuous effort to integrate TypeScript support in a performant and user-friendly manner.
Transcripts
it's crazy to think that node came out
all the way back in 2009 and technically
speaking it still doesn't support
typescript this is one of the big things
that alternatives to node like Dino and
Bun got right early we know that
typescript won it's not a debate anymore
we're not sincerely considering
typescript versus flow anymore
typescript is the language of choice for
the JavaScript ecosystem now it's not
necessarily what we're using in the
browser for all of our web apps and
whatnot but it is absolutely the
language that we're using to build the
tools in the ecosystem surrounding the
project that we now know as node so why
don't we support typescript it's kind of
a complex situation because supporting
typescript means a different thing to
almost everybody for some supporting
typescript means checking the types
making sure everything is valid and
spinning out an error if it's not for
others supporting typescript means you
can put in typescript code and it runs
also important to note that when you
have different things like your TS
config configured in different ways the
result might be entirely different code
or will or will not pass how does this
all get supported in node it's a great
question and we've been going around
this for a while the thing we're here to
talk about today is this awesome new
flag that just got addited to node
before we get there we need to talk
about an important proposal which is the
tc39 proposal for type annotations I've
mentioned this once or twice before it's
a really important proposal the goal of
it is to add type annotations to be part
of the vanilla JavaScript spec not in a
way that they'll be checked and enforced
but in a way that you can copy paste
some types of code in the browser and it
will just run as expected because right
now if I go to my editor and I'll just
write create a quick function in this
file function add numbers and we have a
number B number return if I just copy
paste this into the browser we go to
console paste uncaught syntax error
unexpected token colon because these
colons aren't valid syntax in JavaScript
this syntax only exists for typescript
so I have to delete these and make this
function not type safe in order to go
Define this and now I can add num is
just fine but the fact that you have to
do that is a problem in the goal of the
ecpt proposal here isn't to make it so
type safy is enforced in the browser the
goal is to enable developers to run
programs that are written in typescript
flow and other static typing super sets
of JS without any need for transpilation
this is the key word and we need to
emphasize this one transpilation is most
of what we're talking about here this
proposal is full of really interesting
things let me know if you want a whole
video about it the key motivation is
they wanted to unfor JavaScript clever
pun but the the goal here was to make it
so these other languages weren't as far
from the JavaScript standard and ideally
could all work in the browser the same
way JS does the strong demand for
ergonomic type annotation syntax has led
to Forks of JavaScript with custom
syntax this is introduced developer
friction and means widely used
JavaScript Forks have trouble
coordinating with tc39 and must risk
syntax conflicts this proposal
formalizes an ergonomic syntax space for
comments to integrate the needs of type
checked Forks of JS so this is almost
like colons being used for comments in
JS and then they can be used for types
everywhere else think of it similar to
how JS doc Works where you can leave a
comment on top of a function to Define
the types for it but as part of the
actual typescript in JavaScript syntax
we're doing a colon like this leaves a
comment and then the comma ends the
comment it's a very interesting proposal
that has a lot of potentials for wins
the reason they're doing this is that
very very very many jsds want static
typing in JavaScript also pipe operators
someday fingers crossed I'll get my
beloved pipe operator eventually there's
some interesting discussion at the end
here about how attempts to actually
enforce the types have been done but
these have all resulted in
non-negligible slowdown it's actually
it's fun call it that in 2015 the V8
team which is the team that makes the
engine that powers both node and chrome
they were experimenting with a proposal
to implement a new Js mode that they
called strong mode think of this kind of
like strict mode but stronger where you
could enforce types in type checks and
they intended to use types to improve
site performance Google canel the
experiment in failure in the end we had
to give up on this one yeah it turns out
a lot of these types of things tend to
cause more performance problems than
they resolve it's hard to get right
there are some projects trying to get
this right check out my static Hermes
video all about the custom JavaScript
compiler runtime and whatnot that's goal
is to make your JavaScript code as fast
as the equivalent assembly code really
cool project by facebook/ meta and
Amazon to try and make react native apps
Just instantaneously Launch and run but
these efforts are massive and really
rough which is why this particular
proposal has the goal of treating
typescript like a comment syntax instead
of like a type checked strict language I
think this is awesome I have seen a
problem so many times with how people
use typescript that I think I need to
excal draw so we have the typescript
compiler so we have this high. TS file
and what people seem to think happens is
this comes out and if all of the syntax
here is correct on the other side we get
high. JS which is your Javascript file
this is not actually how the typescript
compiler Works think of the typescript
compiler like two Parts one part is the
type Checker and the other part is the
actual compiler that results in
JavaScript code it's important to know
that the compiler the type Checker side
of it doesn't have to be happy for the
JavaScript to come out so you can think
of this as there's two parts that come
out here it's harder than it looks so
one of the two things that comes out of
the typescript compiler is the actual
output file but the other thing that
comes out is any errors you have so I'll
make error const hello is undefined
so on one hand you might get this file
that as far as the compiler knows could
work could not work it doesn't know
because typescript can have an error on
code that is totally valid like if we
have a function here we'll just call
this add we say a number B number if I
call add with Hello World this is a type
error but this code works so this is why
it's important to understand that these
are separate things that the typescript
compiler both gives you you errors and
anything that it thinks is wrong when it
checks the code as well as the
compilation step where it actually
generates the output JavaScript code the
other important thing to know is that
doing this part where you turn the
typescript into JavaScript is much
easier to do than this part where you
find errors based on the actual syntax
the tree of what's going on in your
typescript code this part is effectively
transpilation where we're turning high.
TS into high. JS we are taking this
input and we are turning it into into
this output the compiler is also the
type Checker which spits out these
errors want to call this distinction out
because I think it's important to know
because right now this proposal isn't a
proposal to check the types and give you
errors if they're wrong this proposal is
to skip the type check and just strip
all the types out so you can run the
JavaScript code without the typescript
syntax breaking it ammed just dropped a
good meme I wanted to include quick
typescript compiler when type checking
here's my code no there's four
places where you used a type that could
be unfolded TS compiler when transpiling
here's my code looks good to me
this is javascript's problem now also of
note I'm not sure if I mentioned this
properly before you don't need to use
the TS compiler to do the transpilation
the actual TSC JavaScript package is
kind of slow and there's a bunch of
other things you can use to take that
typescript code and turn into JS you can
use things like es build swc and so many
other things they say undefined I'm
sorry I reading is hard okay I'm tired
something you'll see on most of my
projects in near the end of my tutorials
is this set of calls here where I ignore
build errors in typescript and I ignore
during Builds on esent the reason for
this is I don't want my typescript type
checking to block my deployments I want
the typescript type checking to be done
in CI so that I know if there's an issue
and it will get flagged before we merge
the code and it goes to main but I don't
want to type check on my deploy as well
as on my CI I'm effectively doing the
same thing here that node is doing where
I'm not checking my types as I'm turning
my typescript into JavaScript I'm just
turning it into JavaScript and then I
have CI that will actually do the type
check I have the pnpm type check and the
pnpm lint call here and these run
separately because again I don't want to
block my deployment on my type checks
and if I can have both of these things
running separately on different
infrastructure it means that my demo app
can be out as quick as possible in a PR
build and that my actual local like Ci
that's running on GitHub can give me the
feedback I need so I know I'm not
shipping a mistake what's the type check
script that's just a super simple
package Json TSC D- no emit cuz again I
don't want the output code I just want
to know that the types are good and this
will throw an error if I get the types
wrong so the goal of this isn't so much
to get you correct errors in your
terminal as you're writing code it's to
make sure you don't need something like
TS node which is a total mess to set up
just to run your typescript code and
this is how other things already work
like if I I'm just going to make a new
file hello. TS
console.log Su nerds you know what we'll
um make this a little more real function
hello name String cool well
console.log hello world thank you super
Maven for flying through this so cool I
made this function as a type definition
and if I try to run this with node I
just do node hello. TS it doesn't know
how to deal with the syntax if I do bun
hello. TS it doesn't give a Doo run
hello. TS same deal yet the idea node's
the only one that doesn't know what to
do with this sadly this does not seem
like something I can easily run right
now because it merged literally 5 hours
ago so there isn't even a like nightly
build up yet hopefully there will be
soon but the least we can do now is read
through what's going on and what the
plan is because I am very excited to
have a strip type built into node node
will transpile the typescript source
code into JavaScript source code during
the transpilation process no type
checking is performed and types are
discarded as it should be checking the
types yourself is not that hard as I
just showed in this code here it's
literally just TSC D- noit now you have
your type Checker it's easy to do
motivation I believe enabling users to
execute typescript files is crucial to
move the ecosystem forward it has been
requested on all of the surveys and it
simply cannot be ignored we must
acknowledge that users want to run node
food. TS without installing external
dependencies or loaders yes absolutely
TS nodes become like a meme and it is
absolutely deserving of being a meme not
because the people who made it or bad
faith or anything but the fact that it
is necessary is relatively pain painful
why type stripping type stripping as the
name suggests means removing all of the
types transforming the input into a JS
module here we see basically the exact
same example I did here where we just
stripped the colon string other run
times also perform transformations of
some typescript only features into
JavaScript for example enums which do
not exist in JS at least initially in
this PR no transformation is performed
meaning that using enum namespace Etc
will not be possible good call out
because there are some things in
typescript that aren't just stripped
like enum becomes something different
because there is no concept of enum in
JavaScript one of the many reasons you
probably shouldn't touch enums but you
get the idea anything that's specific to
how typescript Works won't make it
through this transpilation thankfully
typescripts been more hesitant to add
features that aren't part of vanilla JS
they're a little eager to add some ahead
of time like they added Nish coalesence
optional chaining and some of those
types of features before they made it to
core JavaScript but they only add things
that have been approved that will be
part of CJs in the future which is what
makes this interesting because these
older features that were added before
typescript decided it was going to focus
on being as close to JS as possible
those won't be supported properly so
there will absolutely be some code that
doesn't work with this flag at least for
now but there's a future where that
changes also note is how they're
actually doing the type stripping
because they didn't write a new solution
for this they're actually using s swc
specifically the wasm typescript package
S swc as described is the rust based
platform for the web it's a set of
compilation tools written in Rust to try
and make web dev faster it was
originally just a typescript to
JavaScript compiler to take your
typescript code and make it into a
smaller JS bundle think of this as
similar almost to something like es
build where it's just the minimal takes
the input spits out the output part it's
not a proper bundler that handles all of
the complexity around getting the right
files to the right place making sure
that your bundles are split properly all
of that it's a top level transpiler
almost that turns the typescript code
into JS this is what's being used right
now inside of nextjs to turn your
typescript code into JS that chips to
your users s swc is really cool powerful
project and it's cool seeing it being
adopted in these ways because one of the
things they pushed really hard for was
wasm support not because they expect you
to run s swc in the browser but because
they want s swc to work in every
environment and since node supports wasm
in every environment by supporting WM s
swc can run everywhere without having to
ship a bunch of binaries this is
important because the amount of binaries
that have to ship for S swc and
something like nextjs is honestly a
little bit funny if we go to my node
modules next s swc Darwin arm 64 this is
the version I need cuz I'm on a Mac but
next now has multiple swc versions that
I support for 32-bit and 64-bit Windows
Mac and Linux arm or Intel so there's a
ton of these binaries now that exist in
the next package you thankfully only
need to install a subset of them but not
everything's smart enough to do that
right and you might just have seven
Darwin or not Darwin s swc binaries
floating around on your system now and
these aren't small we reveal and finder
get info that's 100 megabytes just for
the swc arm 64 binding so having a bunch
of those for every operating system
that's not fun which is why shipping s
swc for every single platform as native
binaries inside of node makes no sense
because now you have to eat that for
every single platform and they don't
want to do that they don't want to
massively increase the size of node but
by using the wasm typescript build they
have just one and since wasm runs in
every platform s swc WM can run on every
platform without needing a native binary
it won't be as fast as if they were
using the native binary but now they
have to eat way less like straight up
bundle additions and cruft in order to
get this working as the author says I've
considered other tools but they require
either rust or go to be added to the
tool chain S swc wasm typescript is a
small package with a wasm and ajs file
to bind it s swc is currently used by
Dino for the same purpose it's battle
tested in the future I see this being
implemented in a native layer massive
shout outs to kd1 for releasing an s swc
for us absolutely huge and if we go to
npm we can quickly see that the wasm
typescript package just got updated
first and foremost good to see but more
importantly once npm loads you'll see
it's 2.5 megabytes versus this s version
and S swc Darwin arm 64 much less so 115
Megs yeah just a little bit smaller 115
Megs to 2.8 yeah sorry 2.5 you get the
idea this is pretty much as as
responsible of a way as you can
Implement something like this I'm
honestly really pumped to see it Amaro
is a wrapper around swc wasm typescript
a web assembly Port it's currently used
as an internal and no JS for type
stripping the future it will be possible
to upgrade
separately Aero means bitter in
Italian clever very clever so they added
this new package called Amo that is the
thing that actually does this diff is
too large it's 617 lines what the
do you mean it's too large it said it
was 600 lines oh it's cuz there's a
giant binary here okay I take it back
this is a little absurd is that how
they're including the package they just
took all of it and put it in as text
that's serialized I mean clever that
solves the problem yeah they they parse
this giant blob as a web assembly module
and that's how they intergrate it that
is kind of hilarious I won't lie who
needs to deal with things as complex as
npm and modules when you can just dump
all of the contents as text and then
base 64 encode it and then we have the
dev depths here and you'll notice that
we don't have S swc as one of the depths
because they just dumped the source
there not even the source the like
output binary code that's super cool
it's always fun reading through these
node PRS they're full of fascinating
things node supports both commonjs and
Es module syntax and typescript files
node does node will not convert from one
module system to another if you want
your code to run as an es module you
must Import and Export syntax and if you
want it to run as commonjs you must use
require and module. exports as in
JavaScript files file extensions are
mandatory and import statements and
import Expressions import file TS not
import file because of backwards
compatibility file extensions are also
mandatory and require interesting this
won't work if you're not using the TS or
JS syntax I never thought they would go
that hard on that in node it's the right
decision I know that typescripts been
pushing Us in this direction for a while
but I think most people are going to be
really weird out the first time they see
in a file like this common button. TSX
and as you see here that just breaks for
me which is funny because typescripts
official recommendation is doing that I
think I have a video about that already
if not let me know and I'll consider
doing one so that we can cover that very
very interesting controversial change
but until then I think I've covered all
I have to say on this one this is an
awesome change I am genuinely really
excited to see it crazy to think that
typ scp's been out for 12 years and
node's been out for 14 and we're just
now getting official typescript
supported node but it shows once again
how hard the ecosystem is trying to do
these things right I don't want to fault
node or make it seem like they're a
failure of any form for not supporting
this before they let the ecosystem do
its thing and now that we've done our
thing they're finding the best possible
way to integrate it into the platform so
let me know what you guys think in the
comments and until next time keep using
bun peace nerds
Weitere ähnliche Videos ansehen
Why use Type and not Interface in TypeScript
TypeScript vs JavaScript in 2024 - Difference EXPLAINED
Enums considered harmful
No BS TS #1 - Typescript Setup & Everyday Types
Learn TypeScript For React in 50 Minutes - React TypeScript Beginner Crash Course
Nestjs backend rest api - Ecommerce project. Introduction & setup.
5.0 / 5 (0 votes)