Repository navigation
Function cannot be contextually typed when its rest parameter type is tuple type with leading rest elements #45972
Description
Activity
Assuming we want to support such assignments, I think you don't want
arg6:string | numberarg4:string
If
func3is aFuncthen you should be able to callfunc3(1, 2), soarg4should bestring | numberwhilearg6should bestring | number | undefined.Thank you for pointing out 😃 you're right, I updated my issue comment.
- addedAwaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScriptAn idea for TypeScript
on Sep 23, 2021 graphemecluster commented
on May 29, 2022 ContributorMore actionsAlthough we can wrap all the arguments inside a tuple with rest syntax as a workaround, the type of
arg6is inferred incorrectly tostring | number, which lacksundefined:type Func = (...args: [...strs: string[], num1: number, num2: number]) => void const func: Func = () => {} const func1: Func = (...[arg1]) => {} const func2: Func = (...[arg2, arg3]) => {}; const func3: Func = (...[arg4, arg5, arg6]) => {};
Playground link with the above code
Edit: The above code works because the arguments are being inferred as a whole. Adding types makes it break:
type Func = (...args: [...strs: string[], num1: number, num2: number]) => void // OK const func: Func = () => {} // Error: // Type '(__0_0: string | number) => void' is not assignable to type 'Func'. // Types of parameters '__0_0' and 'strs' are incompatible. // Type '[...strs: string[], num1: number, num2: number]' is not assignable to type '[string | number]'. // Source has 2 element(s) but target allows only 1. const func1: Func = (...[arg1]: [string | number]) => {} // Error: // Type '(__0_0: string | number, __0_1: string | number) => void' is not assignable to type 'Func'. // Types of parameters '__0_0' and 'strs' are incompatible. // Type '[...strs: string[], num1: number, num2: number]' is not assignable to type '[string | number, string | number]'. // Target allows only 2 element(s) but source may have more. const func2: Func = (...[arg2, arg3]: [string | number, string | number]) => {}; // Error: // Type '(__0_0: string | number, __0_1: string | number, __0_2: string | number | undefined) => void' is not assignable to type 'Func'. // Types of parameters '__0_0' and 'strs' are incompatible. // Type '[...strs: string[], num1: number, num2: number]' is not assignable to type '[string | number, string | number, string | number | undefined]'. // Target requires 3 element(s) but source may have fewer. const func3: Func = (...[arg4, arg5, arg6]: [string | number, string | number, string | number | undefined]) => {};
Playground link with the above code
In any case, this issue should be a bug, not a suggestion.
Reacted by uhyo- added a commit that references this issue
on Dec 28, 2022 Andarist commented
on Dec 29, 2022 ContributorMore actionsI'm fixing the primary problem reported in this issue here: #49218 .
That PR doesn't solve the missing
| undefinedproblem though. I think this is a separate discussion and should be handled in a separate PR. In fact, this problem has its own dedicated issue: #46063 (also reported by uhyo (@uhyo) )
Bug Report
🔎 Search Terms
function rest arguments parameter tuple type leading middle rest elements
🕗 Version & Regression Information
4.2.3, 4.3.5, 4.4.2
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
Functions that have one or more arguments (
func1,func2,func3) cannot be assigned to variables of typeFunc.🙂 Expected behavior
No compiler errors and the types of arguments are inferred as:
arg1,arg2,arg3,arg4,arg5:string | numberarg6:string | number | undefined