Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 如何添加Typescript定义以表示请求&;物件_Node.js_Express_Typescript - Fatal编程技术网

Node.js 如何添加Typescript定义以表示请求&;物件

Node.js 如何添加Typescript定义以表示请求&;物件,node.js,express,typescript,Node.js,Express,Typescript,我为我的RESTAPI提供了一组控制器函数,我得到了很多如下信息 error TS7006: Parameter 'req' implicitly has an 'any' type. 同样,对于res。我一直在玩打字等游戏,但没有成功。例如,下面的请求类型参数不起作用 下面是控制器文件的示例。参考路径是正确的 /// <reference path="../../../typings/tsd.d.ts" /> /* globals require */ "use

我为我的RESTAPI提供了一组控制器函数,我得到了很多如下信息

error TS7006: Parameter 'req' implicitly has an 'any' type.
同样,对于
res
。我一直在玩打字等游戏,但没有成功。例如,下面的
请求
类型参数不起作用

下面是控制器文件的示例。参考路径是正确的

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

您可以使用ES6样式命名的导入来仅导入所需的接口,而不是从“express”中以express的形式导入*,后者将包括express本身

首先,确保您已经安装了express的类型定义(
npm install-D@types/express

例如:

// 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);

目前正在使用TypeScript 2.3.4和@types/express 4.0.36。

最好的方法是这样做

//在项目中创建一些共享类型

import { Request, Response, NextFunction } from 'express';
export type MiddlewareFn = (req: Request, res: Response, next: NextFunction) => void;
//然后使用上述类型:

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

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

   // ....
});
从“/my types.d.ts”导入{MiddlewareFn}
router.get('/foo',函数(req,res,next){
// ....
});

每次需要编写中间件函数时都要键入参数,这样您就可以直接键入整个函数,这可能会让人望而生畏

npm i @types/express --save-dev ("@types/express": "^4.17.0")
安装打字机后

// 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) => {
  ...
};

您还应该定义请求参数,而不是安装类型(
@types/express
)。由于每个参数都是字符串,所以接口应该基于字典

以下是一个内联路由处理程序:

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

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

接口GetParams{
[键:字符串]:字符串
参数名称:字符串
}
路由器.get('/:paramName',(req,res)=>{
res.send('参数为'+req.params.paramName)
})

我发现,您可以非常有效地利用TypeScript泛型来围绕Express
请求创建包装

您可以在interfaces文件/文件夹中声明类似的内容:

import { NextFunction, Request, Response } from 'express';

type TypedRequest<
  ReqBody = Record<string, unknown>,
  QueryString = Record<string, unknown>
> = Request<
  Record<string, unknown>,
  Record<string, unknown>,
  Partial<ReqBody>,
  Partial<QueryString>
>;

export type ExpressMiddleware<
  ReqBody = Record<string, unknown>,
  Res = Record<string, unknown>,
  QueryString = Record<string, unknown>
> = (
  req: TypedRequest<ReqBody, QueryString>,
  res: Response<Res>,
  next: NextFunction
) => Promise<void> | void;
从“express”导入{NextFunction,Request,Response};
类型请求<
ReqBody=记录,
查询字符串=记录
>=请求<
记录,
记录,
部分的
部分的
>;
导出型Express中间件<
ReqBody=记录,
Res=记录,
查询字符串=记录
> = (
请求:TypedRequest,
res:答复,
下一步:NextFunction
)=>承诺|无效;
TypedRequest
实际上是Express'
Request
接口的包装器,并用传递给它的泛型填充它,但也是可选的(注意
Record
。然后它还对每个泛型应用
Partial
(您可能希望将其改为
DeepPartial

ExpressMiddleware
采用了3个可选的泛型
ReqBody
Res
QueryString
。它们用于构造一个类似于中间件/控制器的函数签名

然后,您可以按如下方式强键入和消费:

从“../interfaces/ExpressMiddleware”导入{ExpressMiddleware};
输入Req={email:string;密码:string};
类型Res={message:string};
export const signupUser:ExpressMiddleware=async(req,res)=>{

/*强类型`req.body`.yay autocomplete您是否尝试过导出.test=(req:express.Request,res)
?谢谢-这似乎很有帮助,只是它需要我将
import*作为express从“express”;
作为express放在我的控制器中,即使我在代码中没有使用它们。
…req:express.Request.
(大写的E,就像在tsd中一样)?不,这似乎不起作用。感谢你的工作,虽然它起作用了,但它是错的。
paramName
是字符串或未定义的…express Side的垃圾api和类型我正在使用这种方法,需要导入
{Request,Response}
在使用它的每个文件中,是否都有一种方法可以将它导入一次并使其可供整个应用程序使用?
import { NextFunction, Request, Response } from 'express';

type TypedRequest<
  ReqBody = Record<string, unknown>,
  QueryString = Record<string, unknown>
> = Request<
  Record<string, unknown>,
  Record<string, unknown>,
  Partial<ReqBody>,
  Partial<QueryString>
>;

export type ExpressMiddleware<
  ReqBody = Record<string, unknown>,
  Res = Record<string, unknown>,
  QueryString = Record<string, unknown>
> = (
  req: TypedRequest<ReqBody, QueryString>,
  res: Response<Res>,
  next: NextFunction
) => Promise<void> | void;