3

Is it possible to use generics with mapped types in order to map method types?

For example: can you create a mapped type in which you add a first argument of type number to every method?

Pseudo code (won't work)

interface Method<TS extends any[], R> { 
  (...args: TS): R;
}
interface NumberedMethod<TS extends any[], R> { 
  (n: number, ...args: TS): R;
}


type Numbered<T> = {
  // ERROR! Can't use generics here??
  <TS extends any[], R>[K in keyof T]: T[K] extends NumberedMethod<TS, R>? T[K]: T[K] extends Method<TS, R>: NumberedMethod<TS, R>: never;
};

Is there any way in which this is possible?

1 Answer 1

5

If you are trying to extract the generic arguments TS and R from the method, you need to use the infer keyword before a type name in a conditional type (see Type inference in conditional types). This should do what you want:

interface Method<TS extends any[], R> { 
  (...args: TS): R;
}
interface NumberedMethod<TS extends any[], R> { 
  (n: number, ...args: TS): R;
}


type Numbered<T> = {
    [K in keyof T]: T[K] extends Method<infer TS, infer R>? NumberedMethod<TS, R>: T[K];
};

type WithNumber = Numbered<{
    foo : number,
    bar(a: string): void
}> 
// same as 
// type WithNumber = {
//   foo: never;
//   bar: NumberedMethod<[string], void>; // This gets expanded by code completion when accessing the method usually 
// }
Sign up to request clarification or add additional context in comments.

3 Comments

Wow. Conditional types just got a lot more powerful! Thanks for the quick answer.
@nicojs It was there from the beginning just it's a separate feature from vanilla conditional type, but yes infer is mind blowing :)
In your "same as" comment, did you mean foo: number instead of foo: never? (Trying to make sure I understand your black belt type-jitsu is always a good exercise!)

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.