### Instruction:
Implement a real-time chat application using WebSockets in TypeScript, allowing users to send and receive messages instantly. The backend should be built using Node.js and store chat history in a MongoDB database.


### Response:

To implement a real-time chat application using WebSockets in TypeScript, we'll use the following technologies:

1. Node.js with Express for the backend server
2. Socket.IO for WebSocket communication
3. MongoDB to store chat history

First, let's set up our project and install the necessary dependencies.

1. Initialize a new Node.js project:
```
npm init -y
```

2. Install TypeScript and its required packages:
```
npm install typescript ts-node @types/node --save-dev
```

3. Create a `tsconfig.json` file to configure TypeScript:
```json
{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules"]
}
```

4. Install Express, Socket.IO, and MongoDB related packages:
```
npm install express socket.io mongodb @types/express @types/socket.io
```

Now, let's create our application structure:

- src/
  - index.ts
  - app.ts
  - chatController.ts
  - database.ts

Let's start by setting up our Express server and configuring Socket.IO in `app.ts`:

```typescript
// src/app.ts

import express from 'express';
import { Server } from 'socket.io';
import { createServer } from 'http';

const app = express();
const server = createServer(app);
const io = new Server(server);

io.on('connection', (socket) => {
  console.log(`User connected: ${socket.id}`);

  // Handle chat events here

  socket.on('disconnect', () => {
    console.log(`User disconnected: ${socket.id}`);
  });
});

export default server;
```

Next, let's set up our MongoDB connection in `database.ts`:

```typescript
// src/database.ts

import { MongoClient } from 'mongodb';

const uri = 'mongodb://localhost:27017';
const dbName = 'chat-app';

export const connectToDB = async () => {
  try {
    const client = new MongoClient(uri);
    await client.connect();
    console.log('Connected to MongoDB');
    return client.db(dbName);
  } catch (error) {
    console.error('Error connecting to MongoDB', error);
    process.exit(1);
  }
};
```

Now, let's create a chat controller for handling messages and storing them in the database in `chatController.ts`:

```typescript
// src/chatController.ts

import { Socket } from 'socket.io';
import { Db } from 'mongodb';
import { connectToDB } from './database';

let db: Db;

(async () => {
  db = await connectToDB();
})();

interface Message {
  username: string;
  content: string;
  timestamp: Date;
}

export const handleChatEvents = (socket: Socket) => {
  socket.on('message', async (msg: Message) => {
    // Save message to database
    await db.collection('messages').insertOne(msg);

    // Broadcast message to all connected clients
    socket.broadcast.emit('message', msg);
  });
};
```

Next, update `app.ts` to use the chat controller:

```typescript
// src/app.ts

import express from 'express';
import { Server } from 'socket.io';
import { createServer } from 'http';
import { handleChatEvents } from './chatController';

const app = express();
const server = createServer(app);
const io = new Server(server);

io.on('connection', (socket) => {
  console.log(`User connected: ${socket.id}`);

  handleChatEvents(socket);

  socket.on('disconnect', () => {
    console.log(`User disconnected: ${socket.id}`);
  });
});

export default server;
```

Finally, let's create our entry point `index.ts`:

```typescript
// src/index.ts

import app from './app';

const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});
```

Now you can run your application using the following command:

```
npx ts-node src/index.ts
```

This will start a WebSocket server that listens for chat messages and stores them in MongoDB. To build a frontend client to interact with this server, you can use any popular frontend framework like React, Angular, or Vue along with the Socket.IO client library.

Don't forget to add scripts to your `package.json` file to make it easier to run and build your project:

```json
"scripts": {
  "start": "ts-node src/index.ts",
  "build": "tsc",
  "serve": "node dist/index.js"
}
```