-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parameters<...> should always be spreadable #47615
Comments
The type /*[...]*/ action(...args as [any]); |
@RyanCavanaugh Yeah I get that, the issue I do not get is when the hof is a generic on type AnyFn = (...args: readonly unknown[]) => any
const withDispatch = <Action extends AnyFn>(action: Action) => (...args: Parameters<Action>) => dispatch(action(...args)) // no error In my first example I would like to argue that |
I don’t know if this is related but |
@fatcerberus Indeed, but it's the most common and accurate signature of But if we look at it from the statement (statement A):
See the only difference between the two implementations is that one says that the higher order function is bound to operate on any function and the other is bound to operate on a certain set of functions (ActionCreators). I.e. the second is a subset implementation of the first. |
Variance concerns aside, I think the key to why
Emphasis mine. |
I do want to note for the record, however, that this doesn’t follow—it’s the other way around. I can’t implement a generic function where |
Yes you are right, my reasoning was wrong. I think what I was trying to say is that
I get this, but the fact is that we can deterministically say that |
Somewhat surprisingly, For what it's worth, I've always felt there should be better error messages for generic cases like this. Rather than an absolute refusal ("is not assignable to", etc.), the compiler should be clearer that it's only preventing the operation because it can't verify whether it's safe. |
I suggest writing the function like this instead: const dispatch = <T>(action: T) => {
console.log(action)
}
const withDispatch = <A extends unknown[], R>(action: (...args: A) => R) => (...args: A) => dispatch(action(...args)); Or, since the const dispatch = (action: unknown) => {
console.log(action)
}
const withDispatch = <A extends unknown[]>(action: (...args: A) => unknown) => (...args: A) => dispatch(action(...args)); The key difference here is that the types are as specific as possible, revealing to the checker that |
@ahejlsberg For the case of this bug report I've made all functions and types as simple as possible (you should look at all implementations in the example code as arbitrary except where the error is shown). In reality (and as described) I want to allow only a set of specific functions and not The reason for the bug report is to highlight a possible issue with the compiler. |
Right, but my point was that you've chosen the representation |
@ahejlsberg Yes indeed you are right. How ever only functions in the set of
This here is exactly why I created the issue. Because no matter the arguments or non arguments of |
#36874 hmm is this a bug or a design limitation? |
What is a bug but a design limitation persisting? |
Bug Report
🕗 Version & Regression Information
Version: 4.5.4
⏯ Playground Link
Playground link
💻 Code
🙁 Actual behaviour
When creating a higher order function that is going to operate on a certain set of functions TSC tells us
A spread argument must either have a tuple type or be passed to a rest parameter.(2556)
when we try to spread the arguments to it.🙂 Expected behaviour
As with
action.apply(null, args)
andaction.call(null, ...args)
I expect that the inferred type ofParameters
to always be spreadable.The text was updated successfully, but these errors were encountered: