DEV Community

Dak Washbrook
Dak Washbrook

Posted on • Updated on • Originally published at asilearn.org

Extend Express Request in TypeScript

Utilizing the functionality of TypeScript to extend the Request type in Express allowing us to pass our own types to be used with the Request object.

In the example below, I wanted to be able to add a services key to the Express Request object and pass interfaces for Query, Params and Body.

I also reordered some of the types in order of what I most frequently used, making everything optional.

// types.ts
import * as core from 'express-serve-static-core'
import {
  ReportService,
} from './services'

interface IRequestServices {
  ReportService: () => ReportService,
}

export interface Query extends core.Query { }

export interface Params extends core.ParamsDictionary { }

export interface Request<ReqBody = any, ReqQuery = Query, URLParams extends Params = core.ParamsDictionary>
  extends express.Request<URLParams, any, ReqBody, ReqQuery> {
    services: IRequestServices,
  }
Enter fullscreen mode Exit fullscreen mode
// controller.ts
import express from 'express'
import { Params, Query, Request } from '../../types'

interface RequestBody {
  name: string
}

interface RequestQuery extends Query {
  category: string
}

interface RequestParams extends Params {
  reportId: string
}

const updateNameController = async (req: Request<RequestBody, RequestQuery, RequestParams>, res: express.Response): Promise<void> => {
  const reportService = req.services.ReportService()
  const report = await reportService.updateReportName(req.params.reportId, req.query.category, req.body.name)
  return res.status(200)
}

export default updateNameController
Enter fullscreen mode Exit fullscreen mode

Let me know your thoughts in the comments!

Top comments (3)

Collapse
 
sidzan profile image
sijan

Any better way to handle the case where we do not need to extend body and params but only need to extend the Query, example in Get Request for list of items

doing this is kind of messy,

Request<never, never, never, Query>

any suggestions?

Collapse
 
dakdevs profile image
Dak Washbrook

You could rearrange the generics in the interface if your use case is generally using one over the others.

Alternatively, you may create more interfaces that default the others.

eg. RequestWithQuery<Query>

Collapse
 
realsaddy profile image
Jack

Very helpful, thank you