【问题标题】:How to use a Class Decorator in Typescript to modify all of the Classes' Static Methods?如何在 Typescript 中使用类装饰器来修改所有类的静态方法?
【发布时间】:2021-08-17 17:07:59
【问题描述】:

假设我有一个包含许多静态方法的类。我的目标是用函数包装每个静态方法。具体来说,我想通过将.catch 应用于每个静态方法来捕获async 错误,如下所示:

// In user-response.ts

const catchAsyncError = (func: Function) => {
  const catcher = (req: Request, res: Response, next: NextFunction) => {
    func(req, res, next).catch(next);
  }
  return catcher;
}

class UserResponse {
  static createUser = catchAsyncError(createUser);
  static updateUser = catchAsyncError(updateUser);
  static deleteUser = catchAsyncError(deleteUser);
  // more static methods...
}


// In routes.ts

const router = express.Router();

router.post('/create-user', UserResponse.createUser);
router.patch('/update-user', UserResponse.updateUser);
router.delete('/delete-user', UserResponse.deleteUser);

这样做的首要目标是避免代码重复。注意我必须为每个静态方法重复写catchAsyncError(...)

此外,将这些函数放在一个类中的目的是为每个函数添加一些语义上下文。这样,不熟悉各种user相关函数实现的开发者就会知道它们是相关的,因为他们会读到UserResponse.createUser而不是createUser

我正在寻找这样的解决方案:

// In user-response.ts

const catchAsyncError = (func: Function) => {
  const catcher = (req: Request, res: Response, next: NextFunction) => {
    func(req, res, next).catch(next);
  }
  return catcher;
}

@withCatchAsyncError
class UserResponse {
  static createUser = createUser;
  static updateUser = updateUser;
  static deleteUser = deleteUser;
  // more static methods...
}

我将如何实施这样的解决方案?希望这是可能的,因为它比前者更加优雅和美观。

【问题讨论】:

    标签: typescript express class decorator static-methods


    【解决方案1】:

    您的withCatchAsyncError 类装饰器将在运行时获取类构造函数,而没有详细的类型信息。静态类成员实际上是构造函数的属性,所以装饰器需要遍历构造函数的属性,寻找那些本身就是函数的,并用catchAsyncError包装它们。像这样的:

    function withCatchAsyncError(constructor: Function) {
      for (const key of Object.keys(constructor)) {
        if (typeof constructor[key] === 'function') {
          constructor[key] = catchAsyncError(constructor[key]);
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-30
      • 2016-05-19
      • 2016-10-06
      • 2022-08-15
      • 1970-01-01
      • 2016-04-29
      • 1970-01-01
      相关资源
      最近更新 更多