如何在 Typescript 中使用类装饰器来修改所有类的静态方法?



假设我有一个包含许多静态方法的类。我的目标是用一个函数包装每个静态方法。具体来说,我想通过将.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...
}

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

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

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

最新更新