简体   繁体   中英

Argument of type 'NextHandleFunction' is not assignable to parameter of type 'PathParams'

I've got TypeScript up and running with a basic Express server, and I'm running into an issue.

import bodyParser from 'body-parser';
import express, { Express } from 'express';

const app: Express = express();
app.use(bodyParser.json()); // Error 1
app.use(bodyParser.urlencoded({ extended: true })); // Error 2

Error 1 is this:

Property 'pop' is missing in type 'NextHandleFunction'. [2345]

So bodyParser.json() is returning a createServer.NextHandleFunction but doesn't have the pop property. NextHandleFunction is defined like this in @types/connect :

export type NextHandleFunction = (req: http.IncomingMessage, res: http.ServerResponse, next: NextFunction) => void;

Yep, no pop . But what are my options for fixing this?

Error 2 is this:

Type 'NextHandleFunction' is not assignable to type '(string | RegExp)[]'. [2345]

Here, bodyParser.urlencoded() is also returning a createServer.NextHandleFunction , but that's not the type app.use() is looking for.

Again, not sure about my options here.

package.json

"dependencies": {
    "@types/body-parser": "^1.17.0",
    "@types/connect": "^3.4.32",
    "@types/express": "^4.16.0",
    "@types/express-serve-static-core": "^4.16.0",
    "body-parser": "^1.18.3",
    "express": "^4.15.2",
    "express-serve-static-core": "^0.1.1"
},
"devDependencies": {
    "typescript": "^3.1.6"
}

Removing @types/express and @types/express-serve-static-core helped me get rid of those errors, and types are also bundled in express by default. So, don't hesitate to remove them. Also, you don't need body-parser anymore, as json and url-encoded middleware are bundled in express it-self.

I was able to fix the error this way:

import bodyParser from 'body-parser';
import express, { Express, RequestHandler } from 'express';

const app: Express = express();
app.use(bodyParser.json() as RequestHandler);
app.use(bodyParser.urlencoded({ extended: true }) as RequestHandler);

Add this import statement as below in app.ts.

import express, { RequestHandler } from 'express';

also change the express.json() and express.urlencoded({ extended: true }) as below.

this.app.use(express.json() as RequestHandler);
this.app.use(express.urlencoded({ extended: true }) as RequestHandler);

You shouldn't have to cast your middleware, as suggested in the other answers. I believe there may have been some incompatibility between minor @types/* package versions. After removing some type-package dependencies, deleting node_modules/@types , and explicitly installing @types/express , @types/express-serve-static-core , and @types/cookie-parser (you may not need that one), I wound up with (among other things)

        "@types/cookie-parser": "^1.4.2",
        "@types/cors": "^2.8.10",
        "@types/express": "^4.17.12",
        "@types/express-serve-static-core": "^4.17.21",

I am now able to write

import {json, urlencoded} from "express";

...

app.use(urlencoded({extended: false}));

...

app.post("./", json(), this.doPost.bind(this));

These type-check without an explicit cast. I'm not sure exactly what was wrong with the older packages, or if there was some kind of transitive dep de-dupe that picked the wrong combination, but the versions above seem to work together correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM