我正在开发一个名为 expresskit 的库这使您可以使用装饰器为 express 定义路由/参数/等。我正在进行重构,我想我需要限制路由可以具有的响应类型。作为一个例子,这里是现在如何创建路由 -
export default class UserRouter {
@Route('GET', '/user/:userId')
public static getUser(@Param('userId') userId: number): any {
return new User();
}
}
路由应用于静态方法。静态方法可以直接返回一个值,也可以返回一个Promise
。 .我想要求这样的 promise -
export default class UserRouter {
@Route('GET', '/user/:userId')
public static async getUser(@Param('userId') userId: number): Promise<User> {
return Promise.resolve(new User());
}
}
原因是,为了处理不同类型的响应,这些路由背后的逻辑变得臃肿和困惑。由于大多数路由可能是异步的,我宁愿通过依赖异步来获得更清晰的核心代码。我的 Route 装饰器函数看起来像这样-
export default function Route(routeMethod: RouteMethod,
path: string) {
return function(object: any, method: string) {
let config: IRouteConfig = {
name: 'Route',
routeMethod: routeMethod,
path: path
};
DecoratorManager.registerMethodDecorator(object, method, config);
}
}
我创建了一个通用管理器服务来跟踪装饰器的注册位置。在示例中,我可以获得类以及方法名称。我可以稍后像这样引用它- object[method]
.
在我的装饰器上,我想要求类方法是异步的。但是因为我只得到了对象和方法的名称,所以我不知道我是否可以这样做。我怎样才能要求类方法返回 Promise<any>
?
最佳答案
您需要添加一些类型来指示您的装饰器工厂返回一个装饰器函数,该函数仅接受具有预期函数签名的属性描述符 (...any[]) => Promise<any>
.我继续做了一个通用类型别名 RouteFunction
为此:
type RouteMethod = 'GET' | 'POST'; // or whatever your library supports
// The function types the decorator accepts
// Note: if needed, you can restrict the argument types as well!
type RouteFunction<T> = (...args: any[]) => Promise<T>;
// The decorator type that the factory produces
type RouteDecorator<T> = (
object: Object,
method: string,
desc: TypedPropertyDescriptor<RouteFunction<T>> // <<< Magic!
) => TypedPropertyDescriptor<RouteFunction<T>>
// Decorator factory implementation
function Route<T>(routeMethod: RouteMethod, path: string) : RouteDecorator<T> {
return (object, method, desc) => {
// Actual route registration goes here
return desc;
}
}
演示类型检查的示例用法:
class RouteExample {
@Route('GET', 'test1') // works, return type is a Promise
test1(): Promise<number> {
return Promise.resolve(1);
}
@Route('GET', 'test2') // error, return type not a Promise
test2(): number {
return 2;
}
@Route('GET', 'test3') // error, property is a number rather than a function
get test3(): Promise<number> {
return Promise.resolve(3);
}
}
关于node.js - 如何在 Typescript 的方法装饰器上创建编译错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37645970/