Typescript Declaration Merging fail about Express Request

南笙酒味 提交于 2021-02-10 06:15:03

问题


When i extend express request, i got this erorr.

error TS2339: Property 'test' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs>'.

This is my test code that extend request.

app.get('/auth/google/callback', passport.authenticate('google', { failureRedirect: '/login' }),
  function(req: Request, res: Response) {
    req.test = 'aa'
    return console.log(req.test)
});

For solving it, i already searched a lot and i did it.

Make types/express/index.d.ts file. i add typeRoots in tsconfig.json like below.

"typeRoots": ["./node_modules/@types", "./types"],

This is types/express/index.d.ts file and what did i try.

declare namespace Express {
    export interface Request {
        test: string
    }
}

// This is also fail
declare namespace Express {
    interface Request {
        test: string
    }
}

// This is also fail
declare global {
  namespace Express {
    interface Request {
        test: string
    }
  }
}

Even my vscode tell me req.test type is string, server show me error.

This is full erorr on console

[nodemon] starting `ts-node src/app.ts`

/app/node_modules/ts-node/src/index.ts:434
    return new TSError(diagnosticText, diagnosticCodes)
           ^
TSError: ⨯ Unable to compile TypeScript:
src/app.ts(67,9): error TS2339: Property 'test' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs>'.
src/app.ts(68,28): error TS2339: Property 'test' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs>'.

    at createTSError (/app/node_modules/ts-node/src/index.ts:434:12)
    at reportTSError (/app/node_modules/ts-node/src/index.ts:438:19)
    at getOutput (/app/node_modules/ts-node/src/index.ts:578:36)
    at Object.compile (/app/node_modules/ts-node/src/index.ts:775:32)
    at Module.m._compile (/app/node_modules/ts-node/src/index.ts:858:43)
    at Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
    at Object.require.extensions.<computed> [as .ts] (/app/node_modules/ts-node/src/index.ts:861:12)
    at Module.load (internal/modules/cjs/loader.js:986:32)
    at Function.Module._load (internal/modules/cjs/loader.js:879:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)

This is my package.json, as you can see my typescript version is 3.9.6

{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "start": "nodemon --exec ts-node src/app.ts",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "express-session": "^1.17.1",
    "jsonwebtoken": "^8.5.1",
    "nodemon": "^2.0.4",
    "passport": "^0.4.1",
    "passport-google-oauth20": "^2.0.0",
    "ts-node": "^8.10.2"
  },
  "devDependencies": {
    "@types/body-parser": "^1.19.0",
    "@types/cors": "^2.8.6",
    "@types/express": "^4.17.7",
    "@types/express-session": "^1.17.0",
    "@types/jsonwebtoken": "^8.5.0",
    "@types/node": "^14.0.18",
    "@types/passport": "^1.0.4",
    "@types/passport-google-oauth20": "^2.0.3",
    "typescript": "^3.9.6"
  }
}

This is my all tsconfig.json

{
  "compilerOptions": {
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "sourceMap": true,                     /* Generates corresponding '.map' file. */
    "outDir": "./dist",                        /* Redirect output structure to the directory. */
    "removeComments": true,                /* Do not emit comments to output. */
    "strict": true,                           /* Enable all strict type-checking options. */
    "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    "typeRoots": ["./node_modules/@types", "./types"],                       /* List of folders to include type definitions from. */
    "esModuleInterop": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    "skipLibCheck": true,                     /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true  /* Disallow inconsistently-cased references to the same file. */
  },
  "exclude": [
      "nod_modules",
      "**/*.spec.ts"
  ]
}

I spend time and got stress from yesterday. How can i solve it?


回答1:


This seems to be an issue with how you've configured ts-node. To keep things simple and also speed up startup I'd recommend adding -T/--transpile-only to your ts-node arguments, such that your start script becomes nodemon --exec ts-node -T src/app.ts.

This option prevents ts-node from running type checks on your code. This has a few benefits:

  1. You avoid configuration conflicts between tsc (the TypeScript compiler) and ts-node
  2. ts-node starts up much quicker
  3. You can run your server even with compiler failures, which is nice in development.

Note that you never want to commit or merge code that doesn't compile properly with tsc. You can do that by checking this on CI (continous integration) or as a pre-commit hook. If you add "tsc": "tsc" to scripts in package.json you can do npm run tsc or yarn tsc to compile your code.

You can read more about ts-node CLI flags here: https://www.npmjs.com/package/ts-node#cli-and-programmatic-options



来源:https://stackoverflow.com/questions/62926496/typescript-declaration-merging-fail-about-express-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!