RRP*_*RRP 16 node.js typescript
我在我的快递应用程序中有以下代码
router.get('/auth/userInfo', this.validateUser, (req, res) => {
res.json(req.user);
});
Run Code Online (Sandbox Code Playgroud)
我的IDE似乎抱怨错误
错误TS2339:"请求"类型中不存在属性"用户".
当我编译我的打字稿代码时,它似乎抛出了这个错误.任何想法为什么会这样?
Aks*_*tel 22
我们有一个用Express和Typescript编写的大型API,这就是我们处理这些场景的方法:
我们将请求定义保存在一个文件中:
import { Request } from "express"
export interface IGetUserAuthInfoRequest extends Request {
user: string // or any other type
}
Run Code Online (Sandbox Code Playgroud)
然后在我们编写控制器功能的文件中:
import { Response } from "express"
import { IGetUserAuthInfoRequest } from "./definitionfile"
app.get('/auth/userInfo', validateUser, (req: IGetUserAuthInfoRequest, res: Response) => {
res.status(200).json(req.user); // Start calling status function to be compliant with Express 5.0
});
Run Code Online (Sandbox Code Playgroud)
请注意,"user"不是Express的Request对象中本机可用的属性.确保您使用的是将此类属性添加到请求对象的中间件.
Isl*_*her 18
types在“src”文件夹中创建名为的新文件夹<filename>.d.ts在types文件夹中创建文件declare namespace Express {
export interface Request {
user: any
}
}
Run Code Online (Sandbox Code Playgroud)
typeRoots将以下内容添加到tsconfig.json文件中:"typeRoots": [
"./node_module/@types",
"./src/types"
],
Run Code Online (Sandbox Code Playgroud)
Request这样的快递类型:import { Request, Response } from "express";
router.get('/auth/userInfo', this.validateUser, (req: Request, res: Response) => {
res.json(req.user);
});
Run Code Online (Sandbox Code Playgroud)
.ts文件时,您将收到相同的错误,因为 ts-node 会忽略.d.tsfies,除非您--files向package.json脚本添加标志,如下所示:"scripts": {
.
.
"dev": "ts-node --files src/app.ts"
}
Run Code Online (Sandbox Code Playgroud)
小智 12
您需要进行声明合并:
“声明合并意味着编译器将使用相同名称声明的两个单独声明合并为一个定义。”
为此,您可以在项目 src 文件夹(或您想要的任何位置)中创建一个名为 type.d.ts 的文件,其中包含以下内容:
declare namespace Express {
export interface Request {
user: any;
}
export interface Response {
user: any;
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们告诉编译器将用户属性添加到我们的请求和响应定义中。
接下来,我们需要将它附加到我们的 tsconfig.json。
例子:
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"pretty": true,
"sourceMap": true,
"target": "es6",
"outDir": "./dist",
"baseUrl": "./lib"
},
"include": [
"lib/**/*.ts"
],
"exclude": [
"node_modules"
],
"files":["types.d.ts"]
}
Run Code Online (Sandbox Code Playgroud)
现在,打字稿编译器知道 Request 有一个名为 user 的属性,在我的例子中可以接受任何 json 对象。如果需要,您可以限制字符串的类型。
Los*_*lds 11
req可能是“ express”包中的Request类型,并且那里不存在用户。您必须使用自己的路由器处理程序扩展Request或将其强制转换为键入any或object。
尝试res.json(req['user'])或res.json( (<any>req).user )
您也可以使用模块/全局扩充
import { Request } from "express"
declare module "express" {
export interface Request {
user: any
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以制作自己的处理程序包装器(而不是扩展ExpressJs中的Router功能)。
import * as express from 'express';
interface IUserRequest extends express.Request {
user: any
}
function myHandler(handler: (req: IUserRequest, res: express.Response, next?: express.NextFunction) => any) {
return (req: express.Request, res: express.Response, next: express.NextFunction) => {
try {
validateUser(req, res, (err) => { // your validateUser handler that makes a user property in express Request
if(err)
throw err;
let requestWrapper: IUserRequest = <IUserRequest>req;
handler(requestWrapper, res, next);
})
}
catch (ex) {
next(ex);
}
}
}
let app = express();
// init stuff for express but this.validateUser handler is not needed
app.use('/testuser', myHandler((req, res) => {
res.json(req.user);
}));
Run Code Online (Sandbox Code Playgroud)
如果您正在使用ts-node而不是ts-node-dev,请执行以下操作:
typings在您的文件夹中创建一个文件夹src。typings,名称为package您要扩展的文件夹。index.d.ts使用新文件夹创建文件。就我而言,我正在扩展express,我最终得到了这样的结果:
src/
- typings/
- express/
- index.d.ts
Run Code Online (Sandbox Code Playgroud)
在文件中index.d.ts我有这个:
declare module Express {
export interface Request {
bucketUrl: string;
fileName: string;
}
}
Run Code Online (Sandbox Code Playgroud)
请记住更新您的.tsconfig:
{
"compilerOptions": {
"typeRoots" : ["./node_modules/@types", "./typings"]
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
您收到此错误的原因user是本机express Request对象中没有属性的类型定义。您应该为要添加user到请求中的中间件安装类型定义。
例如,如果您将passport库用于JWT身份验证作为中间件:
router.get('/auth/userInfo', passport.authenticate('jwt', {session:false}), (req, res, next) => {
// Get their info from the DB and return it
User.findOne({ email: req.user.email }, (err, user) => {
if (err) {return next(err);}
...
...
Run Code Online (Sandbox Code Playgroud)
您应该为添加类型定义passport:
npm install --save @types/passport
Run Code Online (Sandbox Code Playgroud)
就我而言,使用?来解决问题。
import { Request } from "express";
interface MyUserRequest extends Request {
// Use `user?:` here instead of `user:`.
user?: string;
}
router.get('/auth/userInfo', (req: MyUserRequest, res) => {
res.status(200).json(req.user)
});
Run Code Online (Sandbox Code Playgroud)
只需扩展“Request”而无需声明。
| 归档时间: |
|
| 查看次数: |
14538 次 |
| 最近记录: |