We’ll start by installing TypeScript as a dev dependency. Along with it, we’ll install the the @types declaration packages for Express and Node.js, which provide type definitions in the form of declaration files.
Declaration files are predefined modules that describe the shape of JavaScript values, or the types present, for the TypeScript compiler. Type declarations are usually contained in files with a .d.ts extension. These declaration files are available for all libraries that were originally written in JavaScript, not TypeScript.
The DefinitelyTyped GitHub repository maintains the TypeScript type definitions for use directly in Node.js and other JavaScript projects, so you don’t have to define these types from scratch. To add these types or the declaration files related to a particular library or a module, you have to look for the packages that start with the @types namespace.
// with yarn
yarn add -D typescript @types/express @types/node
// with npm
npm i -D typescript @types/express @types/node
The -D flag, also known as the --dev flag, is a specification for the package manager to install these libraries as devDependencies.
Once these libraries are installed, go to the package.json file where you’ll see a new devDependencies object:
"devDependencies": {
"@types/express": "^4.17.14",
"@types/node": "^18.11.9",
"typescript": "^4.8.4"
}
Now, we have a TypeScript project compiled with some default configuration options. The tsconfig.json file provides these default options and also provides us with the ability to tweak or customize the compiler options.
Typically, the tsconfig.json file lives at the root of the project. To generate it, we’ll use the tsc command:
npx tsc --init
If you open the tsconfig.json file, you’ll see a lot of other compiler options that are commented out. In tsconfig.json, compilerOptions is a mandatory field that needs to be specified. The options used in the config above are:
One option that you will have to enable is called outDir, which specifies where the output will be located after the compilation step. You can search for this option in the tsconfig.json file and uncomment it.
By default, the value of this option is set to the root directory. Change it to dist:
{
"compilerOptions": {
"outDir": "./dist"
// rest options remain same
}
}
While there are probably other configuration options that you can add on to the TypeScript compiler, the options listed above are basic specifications that can help you get started.
Now, you can easily convert the minimal server code in index.js to an index.ts file.
First, rename the file to index.ts. The .ts extension is a file extension that determines what TypeScript files are compiled to JavaScript files later when we build the server.
Open the index.ts file and modify it, as shown below:
import express, { Express, Request, Response } from 'express';
import dotenv from 'dotenv';
dotenv.config();
const app: Express = express();
const port = process.env.PORT;
app.get('/', (req: Request, res: Response) => {
res.send('Express + TypeScript Server');
});
app.listen(port, () => {
console.log(`⚡️[server]: Server is running at https://localhost:${port}`);
});
yarn add -D @types/cors
yarn add -D @types/express-jwt
Watching file changes and build directory Another development-related utility library I like to use when working on Node.js projects is nodemon. nodemon is a tool that helps develop Node.js based applications by automatically restarting the Node.js application when file changes in the directory are detected.
We’ll also install another dev dependency called Concurrently, which will allow us to run multiple commands like nodemon to watch file changes and the tsc command to compile the code:
npm install -D concurrently nodemon
After installing these dev dependencies, update the scripts in the package.json file:
{
"scripts": {
"build": "npx tsc",
"start": "node dist/index.js",
"dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/index.js\""
}
}
The build command will compile the code in JavaScript inside a dist directory. The dev command is used to run the Node.js server in development mode.
Now, go back to the terminal window and run npm run dev to trigger the development server:
TypeScript adds static type safety to a Node.js and Express project with minimal setup overhead. The key steps are: install the type declaration packages, generate and configure tsconfig.json with an outDir, write your source files with .ts extensions, and use concurrently + nodemon to watch and recompile during development.
From here you can extend the setup further — add ESLint with @typescript-eslint, enable stricter compiler options like noImplicitAny and strictNullChecks, or integrate an ORM like Prisma that ships with full TypeScript support out of the box.
Happy coding!
Honestly i am no one, i've just been coding for 3 years now and i like to document every solutions to every problem i encounter. Extracting as much code snippets and tutorials i can so that if i ever need it again i just have to pop back here and get a quick refresher.
Feel free to me through this learning journey by providing any feedback and if you wanna support me: