【问题标题】:How to specify type returned with Express response如何指定快速响应返回的类型
【发布时间】:2018-08-14 04:19:35
【问题描述】:

我正在尝试使用 TypeScript 在我的 express.js Web 应用程序中标准化响应,但我不太确定,如何全局设置响应应该是例如这个接口:

{
  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',
    },
  });
};

有没有办法设置额外的设置,或者重写 typedefs 来实现硬编码的 res.json 类型?

【问题讨论】:

    标签: typescript express


    【解决方案1】:

    很好的解决方案,可确保您在任何 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> };
    

    【讨论】:

      【解决方案2】:

      您不能删除在类型上定义的函数,我们可以通过模块扩充为 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',
              },
          });
      
      }
      

      不幸的是,没有办法强制开发人员使用通用版本(除了长棒),但是通过代码审查,这对您来说可能已经足够好了。

      【讨论】:

        猜你喜欢
        • 2016-02-25
        • 2018-10-22
        • 1970-01-01
        • 2019-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多