【问题标题】:Typescript: Enum Key in Mapped Types打字稿:映射类型中的枚举键
【发布时间】:2018-03-01 08:21:15
【问题描述】:

我有一个 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> = {/*...*/}

并且只想允许将Methods 添加到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 的成员?

【问题讨论】:

    标签: typescript generics enums definition


    【解决方案1】:

    您的问题主要出在:type Route&lt;M extends Methods = any&gt;

    首先,默认值any 将导致MRouteMethodValidator 中的类型为string,因为Route&lt;any&gt;['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>;
    }
    

    【讨论】:

    • 感谢您的想法,但是通过将密钥更改为 [M in HttpMethod],我可以将任何 HttpMethod 添加到验证器,而不仅仅是路由中定义的那些。
    • @SaschaGalley 好的,我现在明白你在做什么了。你能举一个完整的例子,你想做什么以及type Validator应该做什么?
    猜你喜欢
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    • 2021-10-11
    • 2020-12-07
    • 2019-11-19
    • 1970-01-01
    • 2017-03-09
    • 2022-10-25
    相关资源
    最近更新 更多