You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Case that infering type for parameters works for 3.3.0 but error in 3.4.0 #30840
// with compilerOptions.noImplicitAny=true in tsconfig.jsonexportfunctiontest<S>(options: {partial: Partial<S>|undefined}){constfn: any=function(state=options.partial,action_: any){returnstate}returnfn}
Expected behavior:
No error. It's worth noting that it works in 3.3.4.
Actual behavior:
With the tsc command line, it outputs the following errors:
error TS7006: Parameter 'state' implicitly has an 'any' type.
25 const fn: any = function(state = options.partial, action_: any) {
Playground Link:
Related Issues:
The code works in 3.3.4 with no errors, but after upgrading to 3.4.0, the tsc complains that the parameter has 'any' type when the LHSfn is of any type. If I replace fn: any = with fn =, it works for 3.4.0.
However, for the function expression passed as an argument to id we do have a contextual type, namely T. Since T has no constraint we should end up inferring an implicit any type for the parameter, but this isn't quite working correctly.
I don't see why this desirable at all. Unless there are call/construct signatures on the contextual type, this can only create new implicit anys where none were needed. This creates breaks in pretty basic examples (see above comments). What's the motivating example for taking an outerany contextual type (the one typing the function expression, not its parameter) and using that to add implicit anys to initialized parameters?
constk1: any=(m=3)=>m;// m: implicit anyconstk2=(m=3)=>m;// m: number
I would absolutely argue that it is correct for the inferred type of m in the first example to be an implicit any. We know from the contextual type that anything more specific we infer for m will be disregarded, and we have no idea what type of arguments will actually be passed for m (and keep in mind that the default value only kicks in when we're passed an undefined). In the second example it is fine to infer from the initializer because the inferred type will survive and constrain arguments that can be passed for m.
Now, I think where this argument changes is when the contextual type is a generic type with a constraint. Just because the constraint says any doesn't mean that we can't infer a more specific type. So we may have some work to do there.
Possibly related to this, after upgrading from 3.3.1 to 3.4.5, I'm also getting implicit any errors for default parameters in a very specific case (see Case 3):
declarefunctionmemoize<FextendsFunction>(func: F): F;// Case 1: No errorfunctionadd(x: number,y=0): number{returnx+y;}constmemoizedAdd=memoize(add);// Case 2: No errorconstadd2=(x: number,y=0): number=>x+y;constmemoizedAdd2=memoize(add2);// Case 3: Error - Parameter 'y' implicitly has an 'any' typeconstmemoizedAdd3=memoize((x: number,y=0): number=>x+y);
Passing an arrow function expression directly to memoize (in Case 3) results in an implicit any error for default parameter y. For the other two cases, the type of y is correctly inferred as number.
If this is unrelated to the original issue, I'd be happy to move this to a separate one.
Now, I think where this argument changes is when the contextual type is a generic type with a constraint. Just because the constraint says any doesn't mean that we can't infer a more specific type. So we may have some work to do there.
Activity
RyanCavanaugh commentedon Apr 16, 2019
Simpler repro
RyanCavanaugh commentedon Apr 17, 2019
Anders Hejlsberg (@ahejlsberg) Andrew and I were discussing this on teams and I disagree with part of the logic in #28816 (comment)
I don't see why this desirable at all. Unless there are call/construct signatures on the contextual type, this can only create new implicit
anys where none were needed. This creates breaks in pretty basic examples (see above comments). What's the motivating example for taking an outeranycontextual type (the one typing the function expression, not its parameter) and using that to add implicitanys to initialized parameters?jeffryang24 commentedon Apr 17, 2019
Yes, after I upgraded the typescript package to
3.4, suddenly this error showed up and this should not be an issue before3.4.ahejlsberg commentedon Apr 30, 2019
Ryan Cavanaugh (@RyanCavanaugh) Regarding this example:
I would absolutely argue that it is correct for the inferred type of
min the first example to be an implicitany. We know from the contextual type that anything more specific we infer formwill be disregarded, and we have no idea what type of arguments will actually be passed form(and keep in mind that the default value only kicks in when we're passed anundefined). In the second example it is fine to infer from the initializer because the inferred type will survive and constrain arguments that can be passed form.Now, I think where this argument changes is when the contextual type is a generic type with a constraint. Just because the constraint says
anydoesn't mean that we can't infer a more specific type. So we may have some work to do there.bdpartridge commentedon May 15, 2019
Possibly related to this, after upgrading from 3.3.1 to 3.4.5, I'm also getting implicit any errors for default parameters in a very specific case (see Case 3):
Passing an arrow function expression directly to
memoize(in Case 3) results in an implicit any error for default parametery. For the other two cases, the type ofyis correctly inferred asnumber.If this is unrelated to the original issue, I'd be happy to move this to a separate one.
ahejlsberg commentedon May 16, 2019
Braeden Partridge (@bdpartridge) That's exactly the issue I allude to here in my comment:
That's what we need to fix.
bdpartridge commentedon May 16, 2019
Anders Hejlsberg (@ahejlsberg) That makes sense. Thanks for explaining.
christopherthielen commentedon Jun 19, 2019
here's another surprising case:
ahejlsberg commentedon Jan 28, 2020
Braeden Partridge (@bdpartridge) Chris Thielen (@christopherthielen) The issues you point out above are now fixed in #36476.