7

I have an enum for http methods:

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

Then I define a basic method type, that can have any HttpMethod as key:

type Methods = {
  [M in HttpMethod]?: any;
};

A basic Route type could use this Method type:

type Route<M extends Methods = any> = {
  methods: M;
}

So I can define any route like:

interface AnyRoute extends Route<{
  [HttpMethod.GET]: AnyRequestHandler;
}> {}

So far so good. Now I want to add a Validator:

type Validator<R extends Route, M extends HttpMethod> = {/*...*/}

And only want to allow adding Methods to the Validator, that are defined in the Route:

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

Although my IDE seems to understand it, I get the following errors:

  • Type 'M' does not satisfy the constrain 'HttpMethod'.
  • Type 'keyof R["methods"]' is not assignable to type 'HttpMethod'.

Is there any way I can tell typescript, that this is is definitely a member of HttpMethod?

1 Answer 1

4

Your problem mostly lies here: type Route<M extends Methods = any>

First of all, a default value any will result in M being of type string in RouteMethodValidator because Route<any>['methods'] is any and keyof any is string.

Now, changing the default value to Methods still won't solve the problem because you do M extends Methods which basically means that M can have more keys than the ones defined in Methods, i.e. more than are defined in HttpMethods. But in Validator you only allow values of HttpMethods.

I believe your best option would be to make Route not generic.

type Route = {
  methods: Methods;
}

type RouteMethodValidators<R extends Route> = {
  [M in HttpMethod]?: Validator<R, M>;
}
Sign up to request clarification or add additional context in comments.

2 Comments

thanks for your thoughts, but with changing the keys to [M in HttpMethod], I can add any HttpMethod to the Validator, not only the ones defined in the Route.
@SaschaGalley Ok, I see now what you were trying to do. Can you give a full example what you'd like to do and also what type Validator is supposed to do?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.