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