[Today’s random Sourcerer profile: https://sourcerer.io/apricote]

A crash course on TypeScript with Node.js

Adnan Rahić
Sourcerer Blog

--

What if I told you JavaScript could be viable in an enterprise environment? You’d think I was crazy. Isn’t JavaScript that toy of a language used for animating divs from left to right on a web page?

A couple of years ago, I’d agree with you. Not anymore. With the latest advancements in the ECMAScript standard and with the rise of TypeScript, I wouldn’t be surprised with it taking the interwebs with storm. We won’t even know what hit us.

Just like JavaScript, but with types… and intellisense

TypeScript is called “JavaScript that scales” for a good reason. It’s a typed superset of what we’re already so used to. It uses the same syntax and semantics as basic JavaScript, with the addition of some awesome features.

TypeScript compiles to clean, simple JavaScript code which runs on any browser, in Node.js, or in any JavaScript engine that supports ECMAScript 3 (or newer).

TypeScriptlang.org

It supports state of the art JavaScript and lets you use all the newest bells and whistles provided with the latest standards of ECMAScript. And I’m just in love with it. Plain and simple. And, the cherry on top, it’s open source!

Node, server-side JavaScript… or TypeScript?

Before jumping into writing a simple app with Node.js, we should take a minute to explain what it is first. It’s an asynchronous event driven JavaScript runtime built upon Chrome’s V8 JavaScript engine. It’s designed to build scalable network applications.

That being the raw definition, let me clarify. Node.js enables you to write server-side JavaScript. You may now be wondering, how? As you know, JavaScript is a language which runs in a browser. The browser’s engine takes JavaScript code and compiles it into commands. Node.js uses Chrome’s engine and as a runtime for the a server. What do we have now? A way to write JavaScript on the back end.

If I totally lost you with the terms above, take a detour and check this out before coming back and continuing this walk through.

Installing TypeScript

What if I told you installing TypeScript is as easy as installing any module from npm? We’ll you’d have to believe me, because it is. Running one command in your terminal will get you the TypeScript compiler up and running on your machine. Let’s jump in.

You can go ahead and open up a terminal window and create a directory where you want to type some code. I’ll name mine myapp. Initialize npm so you get a package.json file. Then, installing TypeScript is as easy as just running one command.

$ npm init -y
$ npm install -g typescript

This will give your terminal global access to the TypeScript compiler, simply with using the tsc command.

Here’s a simple example. Open up a code editor of your choice and create a simple file. But, give it an extension of .ts. I’ll name my file app.ts.

// app.tslet x: number = 10;
let y: number = 20;
console.log(x + y);

This is a trivial program, only defining two variables and logging their sum. We’re telling the TypeScript compiler to view these variables as numbers. Now when you jump back to the terminal you can compile a JavaScript file from the app.ts TypeScript file.

$ tsc app.ts

Running the command will create an app.js file in the same directory. Opening it up we can see it’s basic ES5 JavaScript.

// app.jsvar x = 10;
var y = 20;
console.log(x + y);

Well, isn’t that awesome? Okay, you may still be a bit skeptic. But, check this out. What if we assign a string value to a : number variable?

let x: number = 'Hello World!';

Change the value of x to 'Hello World!' and run the tsc app.ts command once again. You’ll get a nice error logged back to you.

app.ts(1,5): error TS2322: Type '"Hello World!"' is not assignable to type 'number'.

This is just the tip of the iceberg that’s the awesomeness of TypeScript. If you’re used to running various builds on the front end of your web application, the transition into TypeScript will be a smooth experience. It’s just as running Babel or minification builds for any front-end app.

However, we only want to run the compiled JavaScript files in production. For the development environment we want to use a TypeScript execution environment for Node.js called ts-node. Installing it is as simple as installing TypeScript.

$ npm install -g ts-node

Simple enough. That’s all we need regarding the actual compilers and environments. We’re ready to write some real code.

Installing dependencies

As this would be a proper tutorial without some real code, we need to install some dependencies first. Two of them which make up a large portion of Node apps today are express and body-parser. So what’s Express?

Fast, unopinionated, minimalist web framework for Node.jsOfficial Website

Let’s get crackin’, shall we? Installing the required dependencies is easy, just one command to run.

$ npm install --save express @types/express body-parser

We’re installing express, the express data types for TypeScript, and of course body-parser. This can seem strange. Some @types showing up all of sudden. Not to worry. These types are what make TypeScript special. They’re part of DefinitelyTyped, the repository for high quality TypeScript type definitions. If you need some special types you just install them. That’s just awesome. This let’s the TypeScript compiler know what the special values in Express mean giving it the possibility to do pre-compile error checking correctly.

That was a rather short installation process. Let’s jump to the code.

Hello Node.js… wait, Node.ts?

The application itself will be rather simple, we’ll create a simple server, add two routes, configure it properly and spin it up on a port of our choice. The main thing we need to understand is the folder structure.

Folders are green, files are blue. This is the final layout we want. However, we won’t be creating the dist folder at all. The TypeScript compiler will do it for us during the compilation process. We’ll go through this in more detail a bit further down. But now, let’s create the lib directory and add the two files, the app.ts and server.ts.

Note: Delete the app.ts and app.js files you have in the myapp directory from above when we tried our the tsc command.

1. Making it work

First of all create the lib directory and type this down into your app.ts file.

On line 1 we’re importing the express module we installed previously. Then we create the App class which will instantiate our Node application. Finally we need to export the app property from the instantiated class. With that done let’s add the server.ts.

We’re importing the app and telling it to listen on the port 4040. Pretty simple.

Because I like making sure things work, I tend to check the progress incrementally. So, in that spirit, let’s run the app. In the terminal we want to run the server.ts file with the ts-node module we installed above.

$ ts-node ./lib/server.ts

The terminal should log Express server listening on port 4040 back to you. if it does, we’re set to move on.

2. Configuring the parsing of bodies

The first thing you want when creating a new Node app is to configure the body-parser middleware to parse all incoming request bodies to JSON as well as outgoing responses.

For this we’re creating a private method called config() and just telling the app to use the body-parser middleware. Don’t forget to import the body-parser at the top! This wraps up the configuration step. Let’s add some routes.

3. Where them routes at?

The process of adding routes will be similar to the config. We’ll add another private method, set the routes and tell the app to use them. Sounds simple once you lay it out before you type the code.

In the private routes() method we create an express router and add a .get and .post method. Finally, we just tell the app to use the router and bind it to the / route. We also need to add another import at the top of the file to add the Request and Response types which are used in the router methods.

Just by looking at the code I can’t help myself from enjoying it. The structure and clear overview of everything is just so neat. I could sure get used to this.

4. What about that Insomniac Postman?

The time has come to try it all out. Let’s see if we have any bugs. Run the app once again with ts-node.

$ ts-node ./lib/server.ts

I tend to use either Insomnia or Postman for testing routes, also called REST endpoints. Feel free to install whichever you like if you don’t already have one. They’re simple tools for sending HTTP requests. Here let me show you.

With the app running, open up Insomnia and send an HTTP GET request to http://localhost:4040/.

Just as expected, the response we specified in the code gets sent back. It works fine. Let’s try the POST request too.

Awesome, the JSON object we sent to the endpoint was sent back. That’s exactly what we wrote. Give yourself a pat on the back. The code works as expected!

However, we’re still running the TypeScript files with ts-node. In production we want to compile everything to JavaScript and run it with the node command. But that’s a bit hard if we need to run the tsc command against one file at a time. Luckily, you can pass values to the command line interface and specify options that way, or just create a tsconfig.json file. It’s a special configuration file that specifies everything regarding the actual compilation process.

Setting up the compilation pipeline

With the tsconfig.json file we tell TypeScript what we want to compile and how, as well as where to place the compiled files. There are so many things you can configure, but we’ll focus on the most important things such as the ECMAScript version we want to compile to, which module system to expect and of course the location of the files.

The outDir is set to ./dist, meaning it will create the dist directory and place the complied files there. We’re also specifying the include to add all .ts files located in the lib directory. Now when you run the tsc command, it will read this file and compile everything just as you want. Let’s try it.

$ tsc

Running this you’ll see the new dist directory get created along with the app.js and server.js file. Check it out. The .js files are now basic JavaScript files, written in ES6. To make it easier to run, let’s add some scripts in the package.json.

Open up the package.json. You should have a "scripts" section. Add code so it looks like this:

"scripts": {
"build": "tsc",
"dev": "ts-node ./lib/server.ts",
"start": "node ./dist/server.js",
"prod": "npm run build && npm start"
},

When you run npm run dev in the terminal you will spin up the app with the ts-node module, but if you run the npm run prod command you’ll first build the TypeScript files, and then run the compiled server.js file from the dist folder.

Having scripts to compile the .ts files is important not only for production, but also for running tests. Testing frameworks such as Mocha run basic .js files.

If you want to learn more about testing head over to the article below.

Where to go from here?

Onward and upward. Using TypeScript with tools such as VS Code makes your life as a developer so much easier. It’s awesome at watching your back. The intellisense integration is freaking awesome. It can even be debugged natively! I feel as if TypeScript belongs on the back end. It just fits. Hopefully, it’ll catch on, because I’m loving it.

If you want to take a look at all the code we wrote above, here’s the repository. Or if you want to read my latest articles, head over here.

Hope you guys and girls enjoyed reading this as much as I enjoyed writing it.
Do you think this tutorial will be of help to someone? Do not hesitate to share. If you liked it, smash the clap below so other people will see this here on Medium. Feel free to show us some love by following the Sourcerer Blog!

--

--

Staff Developer Advocate at Tracetest.io part of Kubeshop.io. Failed startup founder, book/course author, and ex-freeCodeCamp local leader.