Reputation: 744
I have the following function and its callback type:
type Callbacks = {
onSuccess: (a: string) => void;
};
function t(event: string, ...args: [...any, Callbacks]) {
}
It works as expected but one thing, onSuccess
function has a string param but TS can't recognize it and says that it has any type but I explicitly set it to string.
t("eventName", "bobo", 123, {onSuccess: (asd) => {
// "asd" is a string but TS says that it's an any
// Parameter 'asd' implicitly has an 'any' type
}})
What should I change in order to let TS recognize the callback's params type because manually specifying them every time is tedious?
P.S. it's a simplified example of my problem
Upvotes: 6
Views: 459
Reputation: 329228
This is currently a missing feature in TypeScript. A function whose parameter list has leading or middle rest elements does not seem to benefit from contextual typing of its input parameters when called. There is a request at microsoft/TypeScript#45972 to change this. It's (as of 2022-07-06) marked as "awaiting more feedback", so if you want to see this changed it wouldn't hurt to give it a 👍 and comment with your use case if you think it's compelling. It wouldn't necessarily help, but I wouldn't hurt.
In the meantime, if you want to work around it, you could make t()
a generic function in a type parameter corresponding to the leading rest tuple. (The original pull request for leading/middle rest elements at microsoft/TypeScript#41544 mentions that generic types are better supported.)
That would look like
function t<T extends any[]>(event: string, ...args: [...T, Callbacks]) {}
And then it works as desired:
t("hello", "bobo", 123, {
onSuccess: (asd) => asd.toUpperCase() // asd is seen as string
})
Upvotes: 5