Typescript 如何指定Express响应返回的类型
我正在尝试用TypeScript标准化我的express.js web应用程序中的响应,但我不太确定如何全局设置响应,例如此界面:Typescript 如何指定Express响应返回的类型,typescript,express,Typescript,Express,我正在尝试用TypeScript标准化我的express.js web应用程序中的响应,但我不太确定如何全局设置响应,例如此界面: { success: boolean, data?: any, error?: string, } 现在我正在写: async (req: Request, res: Response, next: NextFunction) => { try { registerResponse = await register(req.body.
{
success: boolean,
data?: any,
error?: string,
}
现在我正在写:
async (req: Request, res: Response, next: NextFunction) => {
try {
registerResponse = await register(req.body.email, req.body.password);
} catch (error) {
return res.json({
success: false,
error: error.message,
});
}
return res.json({
success: true,
data: {
message: 'Account registered',
},
});
};
有没有办法设置其他设置,或者重写typedef以实现硬编码的res.json类型?您不能删除在类型上定义的函数,我们可以通过模块扩展为
json
函数添加重载,但是这几乎没有什么用处,因为如果我们把属性搞错了,编译器会选择函数的原始版本,允许任何修改
一个更激进的方法是创建一个与Response
兼容的新类型,但它删除了原始的json
方法,并用类型化版本替换它。我们可以使用映射类型,这样就不会复制任何原始类型:
// Helpers
type Diff<T extends string, U extends string> = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T];
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;
// Generic typed response, we omit 'json' and we add a new json method with the desired parameter type
type TypedResponse<T> = Omit<Response, 'json'> & { json(data: T): Response };
// An example of a typed response
type AppResponse = TypedResponse<{
success: boolean,
data?: any,
error?: string,
}>
app.get('/', async (req: Request, res: AppResponse, next: NextFunction) => {
try {
// ....
} catch (error) {
return res.json({
success: false,
error: error.message,
errors: "" // causses error
});
}
return res.json({
success: true,
data: {
message: 'Account registered',
},
});
}
//助手
类型Diff=({[P in T]:P}&{[P in U]:never}&{[x:string]:never}[T];
类型省略=拾取;
//泛型类型响应,我们省略了“json”,并添加了一个具有所需参数类型的新json方法
类型TypedResponse=Omit&{json(数据:T):Response};
//类型化响应的示例
类型AppResponse=TypedResponse
app.get('/',异步(req:Request,res:AppResponse,next:NextFunction)=>{
试一试{
// ....
}捕获(错误){
返回res.json({
成功:错,
错误:error.message,
错误:“”//导致错误
});
}
返回res.json({
成功:没错,
数据:{
消息:“帐户已注册”,
},
});
}
不幸的是,没有办法强迫开发人员使用通用版本(长棒除外),但是通过代码审查,这可能对您来说已经足够好了。这是一个很好的解决方案,可以确保您在任何TypeDoc文档中都有正确的API响应,但是如果您使用如下方法链接,它就不起作用: res.status(200).json(..),因为您仍将使用原始的类型化json()函数。因此,您还需要重新声明计划使用的任何方法,并确保它们返回新的自定义类型,如下所示:
type TypedResponse<T> = Omit<express.Response, 'json' | 'status'> & { json(data: T) : TypedResponse<T> } & { status(code: number): TypedResponse <T> };
TypedResponse=Omit&{json(数据:T):TypedResponse}&{status(代码:number):TypedResponse};