Sas*_*ley 5 generics enums definition typescript
我有一个 http 方法的枚举:
export enum HttpMethod {
  GET = 'GET', POST = 'POST', /*...*/
}
然后我定义了一个基本的方法类型,它可以有 anyHttpMethod作为键:
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'.有什么办法可以告诉打字稿,这绝对是 的成员HttpMethod吗?
你的问题主要出在这里:type Route<M extends Methods = any>
首先,默认值any将导致M类型为stringinRouteMethodValidator因为Route<any>['methods']isany和keyof anyis string。
现在,将默认值更改为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>;
}