我正在尝试用TypeScript标准化我的express.js网络应用中的响应,我不太确定,我怎么能全局设置,响应应该是例如这个接口:
{
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类型?
答案 0 :(得分:1)
你不能删除一个类型上定义的函数,我们可以使用模块扩充为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',
},
});
}
不幸的是,没有办法强迫开发人员使用通用版本(除了长棒),但通过代码审查,这可能对您有用。
答案 1 :(得分:0)
一个好的解决方案,可以确保您在任何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> };