我有一个 http 方法的枚举:

export enum HttpMethod {
  GET = 'GET', POST = 'POST', /*...*/
}

然后我定义了一个基本的方法类型,它可以有任何 HttpMethod 作为键:
type Methods = {
  [M in HttpMethod]?: any;
};

一个基本的 Route 类型可以使用这个 Method 类型:
type Route<M extends Methods = any> = {
  methods: M;
}

所以我可以定义任何路线,如:
interface AnyRoute extends Route<{
  [HttpMethod.GET]: AnyRequestHandler;
}> {}

到现在为止还挺好。现在我想添加一个 Validator :
type Validator<R extends Route, M extends HttpMethod> = {/*...*/}

并且只想允许将 Method s 添加到 Validator 中,在 Route 中定义:
type RouteMethodValidators<R extends Route> = {
  [M in keyof R['methods']]?: Validator<R, M>;
};

虽然我的 IDE 似乎理解它,但我收到以下错误:
  • Type 'M' does not satisfy the constrain 'HttpMethod'.
  • Type 'keyof R["methods"]' is not assignable to type 'HttpMethod'.

  • 有什么办法可以告诉 typescript ,这绝对是 HttpMethod 的成员吗?

    最佳答案

    你的问题主要在这里:type Route<M extends Methods = any>
    首先,默认值 any 将导致 Mstring 中属于 RouteMethodValidator 类型,因为 Route<any>['methods']anykeyof anystring

    现在,将默认值更改为 Methods 仍然不能解决问题,因为您执行 M extends Methods 这基本上意味着 M 可以具有比 Methods 中定义的键更多的键,即比 HttpMethods 中定义的键更多。但是在 Validator 中,您只允许 HttpMethods 的值。

    我相信您最好的选择是使 Route 不通用。

    type Route = {
      methods: Methods;
    }
    
    type RouteMethodValidators<R extends Route> = {
      [M in HttpMethod]?: Validator<R, M>;
    }
    

    关于 typescript :映射类型中的枚举键,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49045364/

    10-10 10:02