@@ -194,7 +194,8 @@ namespace ts.codefix {
194194 case SyntaxKind . Constructor :
195195 return true ;
196196 case SyntaxKind . FunctionExpression :
197- return ! ! declaration . name ;
197+ const parent = declaration . parent ;
198+ return isVariableDeclaration ( parent ) && isIdentifier ( parent . name ) || ! ! declaration . name ;
198199 }
199200 return false ;
200201 }
@@ -335,22 +336,31 @@ namespace ts.codefix {
335336 }
336337
337338 function inferTypeForVariableFromUsage ( token : Identifier , program : Program , cancellationToken : CancellationToken ) : Type {
338- return InferFromReference . inferTypeFromReferences ( getReferences ( token , program , cancellationToken ) , program . getTypeChecker ( ) , cancellationToken ) ;
339+ const references = getReferences ( token , program , cancellationToken ) ;
340+ const checker = program . getTypeChecker ( ) ;
341+ const types = InferFromReference . inferTypesFromReferences ( references , checker , cancellationToken ) ;
342+ return InferFromReference . unifyFromContext ( types , checker ) ;
339343 }
340344
341345 function inferTypeForParametersFromUsage ( containingFunction : FunctionLikeDeclaration , sourceFile : SourceFile , program : Program , cancellationToken : CancellationToken ) : ParameterInference [ ] | undefined {
346+ let searchToken ;
342347 switch ( containingFunction . kind ) {
343348 case SyntaxKind . Constructor :
349+ searchToken = findChildOfKind < Token < SyntaxKind . ConstructorKeyword > > ( containingFunction , SyntaxKind . ConstructorKeyword , sourceFile ) ;
350+ break ;
344351 case SyntaxKind . FunctionExpression :
352+ const parent = containingFunction . parent ;
353+ searchToken = isVariableDeclaration ( parent ) && isIdentifier ( parent . name ) ?
354+ parent . name :
355+ containingFunction . name ;
356+ break ;
345357 case SyntaxKind . FunctionDeclaration :
346358 case SyntaxKind . MethodDeclaration :
347- const isConstructor = containingFunction . kind === SyntaxKind . Constructor ;
348- const searchToken = isConstructor ?
349- findChildOfKind < Token < SyntaxKind . ConstructorKeyword > > ( containingFunction , SyntaxKind . ConstructorKeyword , sourceFile ) :
350- containingFunction . name ;
351- if ( searchToken ) {
352- return InferFromReference . inferTypeForParametersFromReferences ( getReferences ( searchToken , program , cancellationToken ) , containingFunction , program , cancellationToken ) ;
353- }
359+ searchToken = containingFunction . name ;
360+ break ;
361+ }
362+ if ( searchToken ) {
363+ return InferFromReference . inferTypeForParametersFromReferences ( getReferences ( searchToken , program , cancellationToken ) , containingFunction , program , cancellationToken ) ;
354364 }
355365 }
356366
@@ -380,21 +390,20 @@ namespace ts.codefix {
380390 stringIndexContext ?: UsageContext ;
381391 }
382392
383- export function inferTypeFromReferences ( references : ReadonlyArray < Identifier > , checker : TypeChecker , cancellationToken : CancellationToken ) : Type {
393+ export function inferTypesFromReferences ( references : ReadonlyArray < Identifier > , checker : TypeChecker , cancellationToken : CancellationToken ) : Type [ ] {
384394 const usageContext : UsageContext = { } ;
385395 for ( const reference of references ) {
386396 cancellationToken . throwIfCancellationRequested ( ) ;
387397 inferTypeFromContext ( reference , checker , usageContext ) ;
388398 }
389- return unifyFromContext ( inferFromContext ( usageContext , checker ) , checker ) ;
399+ return inferFromContext ( usageContext , checker ) ;
390400 }
391401
392402 export function inferTypeForParametersFromReferences ( references : ReadonlyArray < Identifier > , declaration : FunctionLikeDeclaration , program : Program , cancellationToken : CancellationToken ) : ParameterInference [ ] | undefined {
393403 const checker = program . getTypeChecker ( ) ;
394404 if ( references . length === 0 ) {
395405 return undefined ;
396406 }
397-
398407 if ( ! declaration . parameters ) {
399408 return undefined ;
400409 }
@@ -414,10 +423,8 @@ namespace ts.codefix {
414423 if ( callContext . argumentTypes . length <= parameterIndex ) {
415424 isOptional = isInJSFile ( declaration ) ;
416425 types . push ( checker . getUndefinedType ( ) ) ;
417- continue ;
418426 }
419-
420- if ( isRest ) {
427+ else if ( isRest ) {
421428 for ( let i = parameterIndex ; i < callContext . argumentTypes . length ; i ++ ) {
422429 types . push ( checker . getBaseTypeOfLiteralType ( callContext . argumentTypes [ i ] ) ) ;
423430 }
@@ -426,10 +433,10 @@ namespace ts.codefix {
426433 types . push ( checker . getBaseTypeOfLiteralType ( callContext . argumentTypes [ parameterIndex ] ) ) ;
427434 }
428435 }
429- let type = unifyFromContext ( types , checker ) ;
430- if ( type . flags & TypeFlags . Any && isIdentifier ( parameter . name ) ) {
431- type = inferTypeForVariableFromUsage ( parameter . name , program , cancellationToken ) ;
436+ if ( isIdentifier ( parameter . name ) ) {
437+ types . push ( ...inferTypesFromReferences ( getReferences ( parameter . name , program , cancellationToken ) , checker , cancellationToken ) ) ;
432438 }
439+ const type = unifyFromContext ( types , checker ) ;
433440 return {
434441 type : isRest ? checker . createArrayType ( type ) : type ,
435442 isOptional : isOptional && ! isRest ,
@@ -667,7 +674,7 @@ namespace ts.codefix {
667674 }
668675 }
669676
670- function unifyFromContext ( inferences : ReadonlyArray < Type > , checker : TypeChecker , fallback = checker . getAnyType ( ) ) : Type {
677+ export function unifyFromContext ( inferences : ReadonlyArray < Type > , checker : TypeChecker , fallback = checker . getAnyType ( ) ) : Type {
671678 if ( ! inferences . length ) return fallback ;
672679 const hasNonVacuousType = inferences . some ( i => ! ( i . flags & ( TypeFlags . Any | TypeFlags . Void ) ) ) ;
673680 const hasNonVacuousNonAnonymousType = inferences . some (
0 commit comments