Conquering the Villains: A Journey of Setting Up Node.js with Express and TypeScript
Tags: express, typescript, node, javascript
Published: 2023-05-05 05:27:37

  
> "TypeScript is the Robin to your Batman in the world of JavaScript programming. It's a powerful sidekick that helps you write better code with fewer errors.”
> 

Just like a superhero gains their abilities through a unique process, setting up Node with Express and TypeScript can give you powerful tools to build robust web applications. With Node.js and Express, you can easily create web applications and APIs, and when you add TypeScript to the mix, you gain strong typing and better error checking. Ready to become a web development superhero? Let's dive in!

![Battling against a supervillain](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u2d5ceztfqk34uo20coo.gif)
Let's start our journey by initializing a project, which is where the battle will begin. As any superhero knows, preparation is key to success. So, we'll cast the following spell to make a folder and initialize it with default settings using **`yarn`**:

```bash
mkdir express_ts_setup && cd express_ts_setup
yarn init -y
```

We've successfully initialized our project and let’s add some more friends to our side. Like any good detective in a bat suit , we must be prepared for battle.

Our first challenge is the introverted Node engine. It may seem harmless, but it's a powerful force that can cause chaos if left unchecked. That's why we need to call on the help of our friends and their allies.

We'll invite **`express`** and **`typescript`** to join our superhero squad, but we must also call  **`@types/node`**, and  `@types/express` so `typescript` will understand our `node engine` and `express` It's like calling on your superhero friends to fight a villain, but realizing you also need their allies to win the battle. 💪

```bash
yarn add express typescript @types/node
```

Now, let's create a **`src`** folder where we'll keep our files, and an **`index.ts`** file where our program will start. Like a true superhero, we need to have a strong starting point for our mission.


![Folder structure of the project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ihfpyvwl2u830ll4j1f.png)



With TypeScript on our side, we were ready to take on the battle. But we soon realized that TypeScript was not just any ally - he was a joker, always cracking up jokes about our code. Luckily, he was also a controller, and he helped us keep our code under control.

Despite his humorous nature, we needed TypeScript in our battle, as he was the information broker. He could tell us what was wrong with our code before we even noticed it ourselves. But there was a catch: we had to communicate with him in his own language, Fe2O3. It was a magical language, and only the detective in the bat suit could understand it.

So we armed ourselves with TypeScript, the detective's bat suit, and a good sense of humor, and set out to conquer the world of Node.js with Express and TypeScript.

```bash
// tsconfig.json
{
  "compilerOptions": {
    // Set the ECMAScript version to ES2020
    "target": "ES2020",

    // Use a custom module system called NodeNext
    "module": "NodeNext",

    // Use the nodenext module resolution strategy
    "moduleResolution": "nodenext",

    // Enable compatibility with modules that use `export =` syntax
    "esModuleInterop": true,

    // Allow importing JSON files as modules
    "resolveJsonModule": true,

    // Generate source maps for the compiled code
    "sourceMap": true,

    // Specify the directory where the compiled code will be outputted
    "outDir": "./dist",

    // Enable strict type checking rules
    "strict": true,
  },

  // Specify the files that should be included and excluded in the compilation process
	 "include": ["src/**/*.ts"],
  "exclude": ["node_modules", "dist"]
}
```

And so we continued on our quest, and created the **`index.ts`** file where we would start our magical process. This file would be the entry point to our application, and it would give multiple instructions to our magic.

First, we imported our friends Express and TypeScript, as well as some other helpful tools:

```bash
// we use default spell `express` which is the main spell
// and call named spell`Request` and `Response` which joker will need later
// to understand information, he's a psycho information broker after all
// ofc we will use ES module system 
import express, { Request, Response } from "express";

// instantize an app from express() function
const app = express();

// setup a simple get route 
// and return a test message

app.get("/", (req: Request, res: Response) => {
  res.json({ test: "Ok" });
});

// and finally start the server at port 5000
const PORT = 5000;
app.listen(PORT, () => {
  console.log("server has started on port");
  console.log("http://localhost:" + PORT);
});
```

Excited to see our magical application come to life, we ran the **`node src/index.ts`** command in our terminal, just like we had done before with our JavaScript projects. But instead of seeing our application start up, we were met with an error message:

```bash
import express, { Request, Response } from "express";
^^^^^^

SyntaxError: Cannot use import statement outside a module
```

Great! Now our friend Node understands the magic of ES modules, thanks to our configuration in **`package.json`**.

```json
{
  "name": "expess_ts_setup",
  "version": "1.0.0",
  "main": "index.ts",
  "license": "MIT",
	
	// the new line we add 
	"type": "module", // "commonjs" is defualt, require() syntax
	// ******************
  "dependencies": {
    "@types/node": "^18.16.3",
    "express": "^4.18.2",
    "typescript": "^5.0.4"
  }
}
```

And let’s try again 🙂

`node src/index.ts`

```json
node:internal/errors:464
    ErrorCaptureStackTrace(err);
    ^

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for C:\expess_ts_setup\src\index.ts
```

Ofc it won’t work.
Our friend `node engine` doesn’t understand typescript. We brought `@types/node` so `typescript` could understand `node`

Now it looks like we need another friend to explain `typescript` to `node` 

After some digging around we found out that there’s someone called `ts-node` which can help us do that.
so we called him `yarn add ts-node -D` 

Now instead of calling `node` we call `ts-node`

```json
yarn ts-node src/index.ts
```

However, it seems like we are still encountering an error:

```json
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for C:\expess_ts_setup\src\index.ts
```

We added some more information to our **`tsconfig.json`** file to help **`ts-node`** understand how to transpile our TypeScript code into JavaScript that **`node`** can understand. Here's the updated **`tsconfig.json`** file:

```json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "NodeNext",
    "moduleResolution": "nodenext",
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "sourceMap": true,
    "outDir": "./dist",
    "strict": true,
    "baseUrl": "./",
    "paths": {
      "@controllers": ["src/controllers/index.js"],
      "@router": ["src/router/index.js"],
      "@endPoints": ["src/router/endPoints.enum.js"],
      "@prisma": ["src/config/PrismaClient.js"]
    }
  },
  // "include": ["src/**/*"],

	// ts-node settings we added
  "ts-node": {
    "esm": true,
    "compiler": "typescript"
  }
// *****************
}
```

Oh yesss!! Finally we saw what we wanted to see

```json
server has started on port
http://localhost:5000
```

Great! It's always satisfying to see things working as expected.

Now our magical tool works but we have to restart it every time we add some new features to it.

For that we all to whom to call 🙂

Our good old friend ``nodemon`` , let's call him, `yarn add nodemon -D`

We can now call `yarn nodemon src/index.ts` and our toll won’t have to restart for it to work with new features. 
And lucky for us, since we already have `ts-node` who understands `typescript` , our `nodemon` has learned to work with `ts-node` automatically. 

```json
[nodemon] 2.0.22
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: ts,json
[nodemon] starting `ts-node src\index.ts` // nodemon is starting ts-node Wow!
server has started on port
http://localhost:5000
```

Phew!!
And we have finally make a magical tool that gives us power to build amazing web spell with ease. Don your developer cape and start building today!