网站搜索

TypeScript - 从被装饰函数的类型推断装饰器参数的类型


我想创建一个装饰器,它接受一个字符串数组,这些字符串需要类型安全,并且必须是被装饰函数的一个参数的键的名称。

例如,具有以下设置:

type Params = {id: string};

class Test {
  @requiredParams('id', 'name')
  async handler(request: IRequest<void, Params>): Promise<void> {}
}

应该会有一个类型错误,因为 name 不是 Params 接口的一部分。

到目前为止,我得到的是:

export function requiredParams<
    TRequestParams extends Record<string, string>,
    TRequiredRequestParams extends keyof TRequestParams & string
>(...requiredRequestParams: TRequiredRequestParams[]) {
    return function <
        TThis,
        TArguments extends Parameters<AsyncRequestHandler<any, TRequestParams, any>>,
        TReturn
    >(
        target: (this: TThis, ...args: TArguments) => Promise<TReturn>,
        context: ClassMethodDecoratorContext<TThis, (this: TThis, ...args: TArguments) => Promise<TReturn>>,
    ) {
        return async function(this: TThis, ...args: TArguments): Promise<TReturn> { ... };
    };
}

这里是一些在此使用的类型(部分细节为简略而省略):

type AsyncRequestHandler<
    TBody = any,
    TParams = any,
    TQuery = any
> = (request: IRequest<TBody, TParams, TQuery>, response: IResponse, next?: Next) => Promise<void>;

interface IRequest<TBody = any, TParams = any, TQuery = any> {
    body: TBody;
    params: TParams;
    query: TQuery;
}

顺便说一下,这是使用新的装饰器实现。

附上一个游乐场链接。