Home > OS >  Type of first parameter in object of methods
Type of first parameter in object of methods

Time:11-17

I have a type like this

type d = {
  (e: 'edit', value: boolean): void;
  (e: 'download', value: boolean): void;
  (e: 'delete', value: boolean): void;
}

I want to set the type of a function, which will accept only 'edit' | 'download' | 'delete' i.e. all the e values of type d.

e.g.

function myFunc(e: ??what type??) {
}
myFunc('edit'); // valid type
myFunc('some') // invalid type

CodePudding user response:

Try constructing your callback type by using the Actions instead.

type Action = "edit" | "download" | "delete";
type Callback = (e: Action, value: boolean) => void;

Now you can assign the type

function myFunc(e: Action) { ... }

CodePudding user response:

The problem here is that d is an overloaded function type. Normally, you could use the Parameters utility type to get the type of parameters of a function easily. But Parameters only returns the type of the last overload.

But we can work around this limitation by creating our own utility type which supports N overloads.

type OverloadedParameters<T> = 
    T extends { (...args: infer R1) : any; (...args: infer R2) : any; (...args: infer R3) : any ; (...args: infer R4) : any } ? [R1, R2, R3, R4] :
    T extends { (...args: infer R1) : any; (...args: infer R2) : any; (...args: infer R3) : any } ? [R1, R2, R3] :
    T extends { (...args: infer R1) : any; (...args: infer R2) : any } ? [R1, R2] :
    T extends (...args: infer R) => any ? [R] : any

OverloadedParameters accepts up to 4 overloads. You can expand it to as many overloads as you want. Just follow the pattern.

We now get a tuple containing all the parameter types of the overloaded function d. All that's left to do is to index it with number to get a union of all the parameters and then index it with 0 to get the first element of each union element.

function myFunc(e: OverloadedParameters<d>[number][0]) {}

myFunc('edit') // ok
myFunc('some') // Error

Playground

  • Related