mic*_*cah 3 node.js typescript
我正在开发一个名为expresskit的库,它允许您使用装饰器来定义express的路线/参数/等。我正在重构,我认为我需要限制路由可以具有的响应类型。作为示例,以下是现在创建路由的方式 -
export default class UserRouter {
@Route('GET', '/user/:userId')
public static getUser(@Param('userId') userId: number): any {
return new User();
}
}
Run Code Online (Sandbox Code Playgroud)
路由应用于静态方法。静态方法可以直接返回一个值,也可以返回一个Promise. 我想要求这样的承诺-
export default class UserRouter {
@Route('GET', '/user/:userId')
public static async getUser(@Param('userId') userId: number): Promise<User> {
return Promise.resolve(new User());
}
}
Run Code Online (Sandbox Code Playgroud)
原因是,这些路由背后的逻辑变得臃肿和混乱,无法处理不同类型的响应。由于大多数路由可能是异步的,因此我宁愿通过依赖异步来获得更清晰的核心代码。我的路线装饰器功能如下所示-
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个通用管理器服务来跟踪装饰器的注册位置。在示例中,我可以获得类和方法名称。我可以稍后像这样引用它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;
}
}
Run Code Online (Sandbox Code Playgroud)
演示类型检查的示例用法:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
978 次 |
| 最近记录: |