DEV Community

Cover image for How to setup TypeScript for NodeJS project
Peter Phan
Peter Phan

Posted on • Originally published at peterhub.dev

How to setup TypeScript for NodeJS project

This post was originated on my personal site: https://peterhub.dev

In this short tutorial, we'll go through the process of creating a basic Node+TypeScript application. It's really easy!

Prerequisites

  • You should know about Node + npm and have them installed on your machine

  • You have your favorite IDE ready

TypeScript

TypeScript is a language for application-scale JavaScript. TypeScript adds optional types to JavaScript that support tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript.

This means TypeScript is much better suited for creating long-lasting software and having the compiler help catch bugs and validate types is extremely helpful.


Setup

mkdir typescript-node-example
cd typescript-node-example
npm init -y
npm install --save-dev typescript @types/node ts-node nodemon tsconfig-paths

The first three lines of command are easy to understand, let's see what we've got from line #4.

  1. typescript: Of course we need to install TypeScript. After installing, we have access to the command line TypeScript compiler through the tsc command

  2. @types/node: This package contains type definitions for Node.js. It provides type safety and auto-completion on the Node apis like file, path, process, etc.

  3. ts-node: It allows the app for running TypeScript code directly without being compiled.

  4. nodemon: This will watch for code changes and restart automatically when a file is changed.

  5. tsconfig-paths: We use this to load modules whose location is specified in the paths section of tsconfig.json. More detail here

TypeScript Configuration

We start with npx tsc --init, which will generate tsconfig.json file. The default configuration after removing all commented code:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
}

It won't work yet. We still need to define some properties like outDir, rootDir, baseUrl and paths

  • outDir: Where TypeScript generates our compiled code. We specify it to be in build/ folder.

  • rootDir: This is where TypeScript looks for our code, and we'll write our TypeScript there.

  • baseUrl: Base directory to resolve non-absolute module names. As we don't want relative import path hell like this import {functionA} from "../../../libs/fileA"

  • paths: A series of entries which re-map imports to lookup locations relative to the baseUrl we define above

After that, we have the final version of tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "build",
    "rootDir": "./",
    "baseUrl": "./",
    "paths": {
      "*": ["*", "build/*"]
    }
  }
}

Setup code reloading script

Create file nodemon.json at the root folder (same level as package.json file)

{
  "watch": ["./"],
  "ext": ".ts,.js",
  "ignore": [],
  "exec": "ts-node -r tsconfig-paths/register ./index.ts"
}

Notice -r tsconfig-paths/register part? We'll discuss it later in the Development section

Development

Let's create index.ts and libs/number.ts.

// index.ts
import { randomNumber } from "libs/number";

console.log("Random number (1 - 100): ", randomNumber());

// libs/number.ts
export function randomNumber(): number {
  // random from 1 to 100
  return Math.floor(Math.random() * 99) + 1;
}

The code is pretty straight forward. For the sake of this short tutorial, let's keep it simple like that 😄. In package.json, add "dev": "nodemon" inside scripts. Now we start the application in development with

npm run dev

Earlier I mentioned about -r tsconfig-paths/register part, it means to help ts-node and node to understand absolute path like import ... from "libs/number"

Build

To compile ts files into js, add this line inside scripts in package.json

"build": "rm -rf ./build && npx tsc"

This script will remove old build before the TypeScript compiler injects new code into it.

Production startup

For executing the app in production environment, we have to run build command first, and then run the compiled JavaScript at build/index.js. Those two tasks can be grouped in a script below:

"start": "npm run build && node -r tsconfig-paths/register build/index.js"

After adding all the necessary scripts, this is the entire package.json file

{
  "name": "typescript-node-example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon",
    "build": "rm -rf ./build && npx tsc",
    "start": "npm run build && node -r tsconfig-paths/register build/index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/node": "^14.0.22",
    "nodemon": "^2.0.4",
    "ts-node": "^8.10.2",
    "tsconfig-paths": "^3.9.0",
    "typescript": "^3.9.6"
  }
}

Yeah that was it, simpler than you could imagine 😁

Top comments (0)