Michel Lammens
Michel Lammens

Reputation: 691

TypeScript type annotation for res.body

I'm using typescript for my app node.js express. I would like say the res.body is type personne. I have tried this:

router.post('/',(req: Request, res: Response) => {
   const defunt:PersoneModel = res.(<PersoneModel>body);
}

I have this model:

export type PersoneModel = mongoose.Document & {
  nom: String,
  prenom: String,
}

Can you help me?

Thank you.

Upvotes: 51

Views: 77383

Answers (4)

Chandler Price
Chandler Price

Reputation: 31

Here is what worked for me (I am using node, express, and a postgres Pool connection):

import express, { Response, Request } from 'express';

export interface ITeamsRequest {
  teams?: ITeam[];
  divisions?: ITournamentDivision[];
}

export function setupTeams(app: express.Application, client: Pool) {
  app.get(
    '/teams',
    async (req: Request, res: Response<ITeamsRequest>) => {
        const teams = // get teams;
        const divisions = // get divisions;
        res.status(200);
        return res.json({ teams, divisions });
    },
  );
}

The key thing is to manually import Request and Response, and using a type generic (Response<ITeamsRequest>) you can define your own ResBody type.

This was on express version 4.17.1 and @types/express 4.17.11

Upvotes: 3

Acid Coder
Acid Coder

Reputation: 2746

router.post('/',(req: Omit<Request,'body'> & { body: PersoneModel }, res: Response) => {
   // code
}

this also will do, useful if you want to create abstration

Upvotes: 4

onoya
onoya

Reputation: 2478

Update:

As of @types/[email protected], the Request type uses generics.

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/express/index.d.ts#L107

interface Request<P extends core.Params = core.ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = core.Query> extends core.Request<P, ResBody, ReqBody, ReqQuery> { }

You could set the type of req.body to PersoneModel like this:

import { Request, Response } from 'express';

router.post('/',(req: Request<{}, {}, PersoneModel>, res: Response) => {
   // req.body is now PersoneModel
}

For @types/[email protected] and below

Encountered similar problem and I solved it using generics:

import { Request, Response } from 'express';

interface PersoneModel extends mongoose.Document {
  nom: String,
  prenom: String,
}

interface CustomRequest<T> extends Request {
  body: T
}

router.post('/',(req: CustomRequest<PersoneModel>, res: Response) => {
   // req.body is now PersoneModel
}

Upvotes: 129

gokcand
gokcand

Reputation: 6836

We can use as. This should be enough to imply that res.body is PersoneModel

 const defunt = res.body as PersoneModel;

However more straightforward way is declaring type of the variable as a PersoneModel

 const defunt: PersoneModel = res.body;

Upvotes: 30

Related Questions