8. TypeScript - In Node.js
Superset of JavaScript, adds static typing, interfaces, generics, etc.
Compiles down to plain JavaScript.
INSTALLATIONS
npm init -y
npm install typescript ts-node @types/node --save-dev
npx tsc --init
//ts-node: run .ts files directly.
//@types/node: type definitions for Node.js core modules.
Change Some settings in ts.config
"outDir": "./dist",
"lib": ["esnext"],
"types": ["node"],
Changes in package.json
"scripts": {
"build":"tsc", //convert ts into js
"start":"node dist/index.js", // In the dist folder our index.js file run
"dev":"ts-node index.ts" // run our ts file
},
npm run build // convert ts to plain js in dist
npm run dev // run ts file
npm start // run js file inside dist ts and js file both give same result
BASIC TYPES
//Basic types
let isDone:Boolean = false;
let name:String = "Ayush";
let num: number = 23;
let list:number[] = [1,2,3,4,5] // Array<number> also works
let randomVal: any ="hey" // type is any - string number boolean
let abc :[string , number] = ["hi",66] //tuple
enum Color{
Blue , Green , Red
}
let d:Color = Color.Blue
Interfaces
Interface define the structure/shape of the object or data. Let suppose we have User having name , id ,email . So we need to verify its types before creating User.
// Interface
interface User{
name: String;
id:number;
email?:string;
readonly createdAt: Date;
}
const user : User ={
name:'Ayush',
id:1,
createdAt:new Date(),
}
//type
type Product ={
title:string,
price:number
}
const product1 : Product={
title:"One plus nord 5",
price:32000,
}
Functions
//functions with type annotations
function add(a:number,b:number):number{
return a+b;
}
//with arrow function
const mul = (a:number,b:number):number=> {
return a*b;
}
function greet(a:string , greeting?:string){ // here greeting is optional to pass
return `${a} + ${greeting}`
}
TypeScript With Node.js and Express.js Integration
npm install express nodemon
npm install @types/express --save-dev
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"dev": "nodemon index.ts"
},
import express ,{Express , NextFunction, Request , Response} from 'express';
const app:Express = express();
const port:number = 3000;
app.use(express.json())
interface CustomRequest extends Request{
startTime?:number
}
//use middleware
app.use((req:CustomRequest , res:Response , next: NextFunction)=>{
req.startTime = Date.now();
next();
})
// req -> Request<p->like dynimic value /:id, ResBody-> res body like res.json , res.send , ReqBody-> need to create interface destrcutres data types , ReqQuery, Locals>
app.get('/' , (req:Request,res:Response)=>{
res.send("Hello Express js with typeScript")
})
//post route -> new user : name , email - req.body
// /user/:id?name -> Request<{},{},{},{}>
interface User{
name:string,
email:string
}
app.post('/user', (req:Request<{}, {}, User> ,res:Response)=>{
const{name , email}= req.body;
res.status(200).json({
sucess:true,
message:"User creted"
})
})
//user bases id
app.get('/user/:id', (req:Request<{id:String}> ,res:Response)=>{
const{id} = req.params;
res.json({
userId:id
})
})
app.listen(port , ()=>{
console.log(`Server is running at ${port}`)
})
Mongoose models using Typscript
npm i mongoose
npm i @types/mongoose --save-dev
import mongoose, { Document, Schema } from 'mongoose'
export interface IUser extends Document { // we export this cuz we use this in our controller
name: string; // const users : IUser[]= await User.find(...)
email: string;
password: string;
createdAt: Date;
}
const userSchema = new Schema<IUser>({
name: { type: String, required: true },
email: { type: String, required: true },
password: { type: String, required: true },
createdAt: Date
});
export default mongoose.model<IUser>("User", userSchema);