Typescript and Node.js Tutorial for the Backend (Beginner)

Typescript has become a popular tool to reduce errors when writing JavaScript. It was developed by Microsoft and gained a lot of popularity when Angular adopted it as a first level citizen. When Angular 2 was nearing completion, the only docs available were for Typescript.

Typescript doesn’t only work for browser or frontend code, you can also choose to write your backend applications in it if you want to use Node.js but have some additional type safety and the other abstraction that the language brings.

Typescript and Node Starter

This post is written on the following software versions (for future reference)

node: v9.3.0
npm: 5.5.1

Firstly, let’s create our project directory and initialise it as a node project:

mkdir typescript-node
cd typescript-node
npm init -y
npm i --save-dev ts-node

The Typescript compiler takes options in the shape of a tsconfig.json file that determines where to put built files and in general is pretty similar to a babel or webpack config.

Mine looks like this for this simple example:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "declaration": true,
    "outDir": "build"
  }
}

Hello World in Typescript and Node.js

Let’s install the default Typescript compiler and get our Hello World up and running:

npm i -g typescript
mkdir src
touch src/index.ts

If you know place any JavaScript (or Typescript) in your index.ts file, like:

console.log('Hello World!');

you’ll be able to compile it by simply typing tsc. This should create a build directory with a file.

Your directory tree now should look a bit like this:

├── build
│   ├── index.d.ts
│   └── index.js
├── node_modules
├── package.json
├── package-lock.json
├── src
│   └── index.ts
└── tsconfig.json

Now you can run your compiled version with the regular node binary:

node build/index.js

Automatically Watch and build / compile Typescript code

When we change a file in our code, we want our application or server to automatically restart, so we don’t have to do that manually and have a better development experience.

nodemon is a pretty nice tool to achieve this, so let’s install it globally with your preferred package manager:

npm i -g nodemon

To be able to run our Typescript code as if it was vanilla JavaScript, we can make use of ts-node and just point it at our desired files.

So to keep executing our code while developing, we’ll add an npm command like so to our package.json (you can also run this manually:

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "start": "nodemon --exec ./node_modules/.bin/ts-node -- ./src/index.ts"
},

Output:

> typescript-node@1.0.0 start /home/jonathan/projects/typescript-node
> nodemon --exec ./node_modules/.bin/ts-node -- ./src/index.ts

[nodemon] 1.14.11
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `./node_modules/.bin/ts-node ./src/index.ts`
Hello World!
[nodemon] clean exit - waiting for changes before restart

Your First Typescript Module (require vs import)

The JavaScript ecosystem heavily relies on modules and importing them in Typescript is basically like using ES6+ / ES2015+ in the browser.

Instead of the node typical require we’ll use import. If you attempt to use require you’ll likely get an error message like the one below:

src/index.ts(1,10): error TS2304: Cannot find name 'require'.

Let’s go ahead and create our own Typescript module, just containing a simple function called greeter.ts in our src directory:

export function Greeter(name:string): string {
  return 'Hello there, ' + name + '!';
}

Note that the Greeter function has string written all over it. This is because we want to tell the compiler that this function will always expect to get a piece of text and it should always return a piece of text. This is the type safety, that we verbosely write into our functions, that makes Typescript code less error prone in many instances.

We can now import the function in our index.ts file and start using it. Let’s pay attention to how we import it and change our index file to:

import { Greeter } from "./greeter";

console.log(Greeter('Jonathan'));

When you run it, the expected output is Hello there, Jonathan!.

Summary

That’s the basics of getting started with Typescript and Node, let me know what you think in the comments, if you have any questions or hit me up on twitter

Thank you for reading! If you have any comments, additions or questions, please leave them in the form below! You can also tweet them at me

If you want to read more like this, follow me on feedly or other rss readers

2 thoughts on “Typescript and Node.js Tutorial for the Backend (Beginner)”

  1. Great article, thanks.

    How do you suggest handling dynamic exports? TS (es6 modules really) doesn’t allow for this. Usually I would create a module in Node which returns a configuration json object which depends on the environment (development, production).

    How to do this in TS?
    The only thing I can think of is having a script replace a “configuration.ts” module before running nodemon… .. I believe Angular-Cli does this with its environments file..

    1. Maybe a switch in a webpack config with a module export for the correct file to include?

      Or a simple switch on the process environment

Leave a Reply

Your email address will not be published. Required fields are marked *