Absolutely, using TypeScript will enhance your code quality by adding static typing, which can help catch errors at compile time rather than at runtime. Here's how you can adjust your MongoDB and Mongoose setup for your Task Manager application using TypeScript:
### 1. Initialize TypeScript
First, ensure TypeScript is installed in your project. If it's not, you can add it along with the necessary types for Node.js and Mongoose:
```bash
npm install typescript @types/node @types/mongoose --save-dev
```
Then, initialize a TypeScript configuration file (`tsconfig.json`) if you haven't already:
```bash
npx tsc --init
```
Adjust the `tsconfig.json` as needed for your project setup.
### 2. Update the Database Connection File (`db.ts`)
Create or update your database connection file with TypeScript typings:
```typescript
// config/db.ts
import mongoose from 'mongoose';
const connectDB = async (): Promise<void> => {
try {
const conn = await mongoose.connect('mongodb://localhost/taskmanager');
console.log(`MongoDB Connected: ${conn.connection.host}`);
} catch (error) {
console.error(`Error: ${error}`);
process.exit(1);
}
};
export default connectDB;
```
### 3. Define a Mongoose Model with TypeScript (`Task.ts`)
Here's how you define a Mongoose model with TypeScript:
```typescript
// models/Task.ts
import { model, Schema, Document } from 'mongoose';
interface ITask extends Document {
title: string;
description?: string;
priority: 'Low' | 'Medium' | 'High';
deadline?: Date;
status: 'Pending' | 'In Progress' | 'Completed';
createdAt?: Date;
updatedAt?: Date;
}
const taskSchema: Schema = new Schema({
title: { type: String, required: true },
description: { type: String, required: false },
priority: { type: String, required: true, enum: ['Low', 'Medium', 'High'] },
deadline: { type: Date, required: false },
status: { type: String, required: true, default: 'Pending', enum: ['Pending', 'In Progress', 'Completed'] },
createdAt: { type: Date, default: Date.now },
updatedAt: { type: Date, default: Date.now }
});
const Task = model<ITask>('Task', taskSchema);
export default Task;
```
### 4. Use the Model in Your Application
When you create, read, update, or delete tasks in your controllers, you can now benefit from TypeScript's type checking. For instance, when creating a new task:
```typescript
// Somewhere in your controller or service file
import Task from '../models/Task';
const createTask = async (taskData: ITask) => {
try {
const task = new Task(taskData);
await task.save();
console.log('Task created:', task);
} catch (error) {
console.error('Error creating task:', error);
}
};
```
### 5. Adjust the Project Structure
With TypeScript, you might want to adjust your project structure slightly to separate the source files from the compiled JavaScript files:
```
/task-manager
|-- /backend
| |-- /src
| |-- /config
| | |-- db.ts
| |-- /models
| | |-- Task.ts
| |-- /routes
| | |-- taskRoutes.ts
| |-- /controllers
| | |-- taskController.ts
| |-- /middlewares
| | |-- errorMiddleware.ts
| |-- /utils
| |-- server.ts
| |-- /dist (compiled JavaScript files)
| |-- package.json
| |-- tsconfig.json
|-- /frontend
```
Ensure your `tsconfig.json` is set up to compile the TypeScript files from the `src` directory to the `dist` directory.
By integrating TypeScript, your Task Manager backend will be more robust, catching potential issues at compile time and providing auto-completion and code documentation benefits as you develop.