In this tutorial, we will be using TypeScript on both sides (server and client) to build a Todo App from scratch with React, NodeJS, Express, and MongoDB.
So, let’s start by planning the API.
Let’s dive in.
To create a new NodeJS App, you need to run this command on the terminal:
yarn init
It will ask for a couple of questions and then initialize the app. You can skip it by adding a -y
flag to the command.
Next, structure the project as follows:
├── dist
├── node_modules
├── src
├── app.ts
├── controllers
| └── todos
| └── index.ts
├── models
| └── todo.ts
├── routes
| └── index.ts
└── types
└── todo.ts
├── nodemon.json
├── package.json
├── tsconfig.json
As you can see, this file structure is relatively simple. The dist
directory will serve as an output folder once the code has compiled to plain JavaScript.
We also have an app.ts
file that is the entry point of the server. The controllers, types, and routes are also in their respective folder names.
Now, we need to configure the tsconfig.json
file to help the compiler along following our preferences.
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "dist/js",
"rootDir": "src",
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["src/types/*.ts", "node_modules", ".vscode"]
}
Here we have four main properties to underline:
outDir
: tells the compiler to put the compiled code into the dist/js
folder.
rootDir
: informs TypeScript to compile every .ts
file located in the src
folder.
include
: tells the compiler to include files that are in the src
directory and sub-directory.
exclude
: will exclude the files or folders passed in the array during compile-time.
We can now install the dependencies to enable TypeScript in the project. Because by default, this app will use JavaScript.
There are two ways of using TypeScript in a NodeJS app. Either locally in the project or globally in our machine. I will go for the latter based on personal preference, but you can stick with the local way if you want too.
Now, let’s execute the following command on the terminal to install TypeScript.
yarn add typescript -g
This g
flag allows installing TypeScript globally and this makes it accessible from anywhere on the computer.
Next, let’s add some dependencies in order to use Express and MongoDB.
yarn add express cors mongoose
We also need to install their types as development dependencies to help the TypeScript compiler understand the packages.
yarn add -D @types/node @types/express @types/mongoose @types/cors
Now, TypeScript won’t yell at you anymore - it will use these types to define the libraries we’ve just installed.
We also need to add other dependencies to be able to compile the TypeScript code and start the server concurrently.
yarn add -D concurrently nodemon
With that in place, we can now update the package.json
file with the scripts needed to start the server.
"scripts": {
"build": "tsc",
"start": "concurrently \"tsc -w\" \"nodemon dist/js/app.js\""
}
concurrently
will help compile the TypeScript code, keep watching for changes, and also start the server simultaneously. That said, we can now launch the server - however, we have not created something meaningful yet in that regard. So, let’s fix that in the next section.
import { Document } from "mongoose"
export interface ITodo extends Document {
name: string
description: string
status: boolean
}
Here, we have a Todo interface that extends the Document
type provided by mongoose
. We will be using it later to interact with MongoDB. That said, we can now define how a Todo model should look.
import { ITodo } from "./../types/todo"
import { model, Schema } from "mongoose"
const todoSchema: Schema = new Schema(
{
name: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
status: {
type: Boolean,
required: true,
},
},
{ timestamps: true }
)
export default model<ITodo>("Todo", todoSchema)
As you can see here, we start by importing the interface ITodo
and some utilities from mongoose
. The latter helps to define the Todo schema and also pass in ITodo
as a type to the model
before exporting it.
With that, we can now use the Todo model in other files to interact with the database.
#typescript #react #node #mongodb #developer