How to add Typescript definitions to Express req &

2020-07-08 06:45发布

问题:

I have a set of controller functions for my REST API and I'm getting lots of the following

error TS7006: Parameter 'req' implicitly has an 'any' type.

Likewise for res. I've been playing around with typeings etc. but with no success. For example the Request type parameter below does NOT work.

Here is an example of the controller files. The reference path is correct.

/// <reference path="../../../typings/tsd.d.ts" />    
/* globals require */    
"use strict";    
exports.test = (req : Request, res) => {

I tried adding import * as express from "express"; into the file - I don't need it normally as these functions are exported and use by index.js which actually implements the routing.

And this is tsd.d.ts

/// <reference path="requirejs/require.d.ts" />
/// <reference path="express/express.d.ts" />
/// <reference path="mime/mime.d.ts" />
/// <reference path="node/node.d.ts" />
/// <reference path="serve-static/serve-static.d.ts" />
/// <reference path="bluebird/bluebird.d.ts" />
/// <reference path="mongoose/mongoose.d.ts" />

回答1:

You can use ES6 style named imports to import only the interfaces you need, rather than import * as express from 'express' which would include express itself.

First make sure you have installed the type definitions for express (npm install -D @types/express).

Example:

// middleware/authCheck.ts
import { Request, Response, NextFunction } from 'express';

export const authCheckMiddleware = (req: Request, res: Response, next: NextFunction) => {
  ...
};

// server.ts
import { authCheckMiddleware } from './middleware/authCheck';
app.use('/api', authCheckMiddleware);

Currently using TypeScript 2.3.4 and @types/express 4.0.36.

I had the same question so I thought I'd provide an answer in case anyone else comes across this.



回答2:

It can be daunting to type the arguments every time you need to write middleware functions so you can just type the whole function directly too.

npm i @types/express --save-dev ("@types/express": "^4.17.0")

After installing typings..

// This can be shortened..
import { Request, Response, NextFunction } from 'express';
export const myMiddleware = (req: Request, res: Response, next: NextFunction) => {
  ...
};

// to this..
import { RequestHandler } from 'express';
export const myMiddleware: RequestHandler = (req, res, next) => {
  ...
};

// or in case it handles the error object
import { ErrorRequestHandler } from 'express';
export const myMiddleware: ErrorRequestHandler = (err, req, res, next) => {
  ...
};


回答3:

The best way to do this is like so.

// create some shared types in your project

import { Request, Response, NextFunction } from 'express';
export type MiddlewareFn = (req: Request, res: Response, next: NextFunction) => void;

// then use the above types:

import {MiddlewareFn} from './my-types.d.ts'

router.get('/foo', <MiddlewareFn>function (req, res, next) {

   // ....
});


回答4:

Rather than installing types(@types/express) you should also define request parameters. Since every parameter is string, interface should base on dictionary.

Here is an inline route handler:

interface GetParams {
  [key: string]: string
  paramName: string
}

router.get<GetParams>('/:paramName', (req, res) => {
  res.send('Parameter is ' + req.params.paramName)
})