@@ -194,7 +194,8 @@ namespace ts.codefix {
194
194
case SyntaxKind . Constructor :
195
195
return true ;
196
196
case SyntaxKind . FunctionExpression :
197
- return ! ! declaration . name ;
197
+ const parent = declaration . parent ;
198
+ return isVariableDeclaration ( parent ) && isIdentifier ( parent . name ) || ! ! declaration . name ;
198
199
}
199
200
return false ;
200
201
}
@@ -335,22 +336,31 @@ namespace ts.codefix {
335
336
}
336
337
337
338
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 ) ;
339
343
}
340
344
341
345
function inferTypeForParametersFromUsage ( containingFunction : FunctionLikeDeclaration , sourceFile : SourceFile , program : Program , cancellationToken : CancellationToken ) : ParameterInference [ ] | undefined {
346
+ let searchToken ;
342
347
switch ( containingFunction . kind ) {
343
348
case SyntaxKind . Constructor :
349
+ searchToken = findChildOfKind < Token < SyntaxKind . ConstructorKeyword > > ( containingFunction , SyntaxKind . ConstructorKeyword , sourceFile ) ;
350
+ break ;
344
351
case SyntaxKind . FunctionExpression :
352
+ const parent = containingFunction . parent ;
353
+ searchToken = isVariableDeclaration ( parent ) && isIdentifier ( parent . name ) ?
354
+ parent . name :
355
+ containingFunction . name ;
356
+ break ;
345
357
case SyntaxKind . FunctionDeclaration :
346
358
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 ) ;
354
364
}
355
365
}
356
366
@@ -380,21 +390,20 @@ namespace ts.codefix {
380
390
stringIndexContext ?: UsageContext ;
381
391
}
382
392
383
- export function inferTypeFromReferences ( references : ReadonlyArray < Identifier > , checker : TypeChecker , cancellationToken : CancellationToken ) : Type {
393
+ export function inferTypesFromReferences ( references : ReadonlyArray < Identifier > , checker : TypeChecker , cancellationToken : CancellationToken ) : Type [ ] {
384
394
const usageContext : UsageContext = { } ;
385
395
for ( const reference of references ) {
386
396
cancellationToken . throwIfCancellationRequested ( ) ;
387
397
inferTypeFromContext ( reference , checker , usageContext ) ;
388
398
}
389
- return unifyFromContext ( inferFromContext ( usageContext , checker ) , checker ) ;
399
+ return inferFromContext ( usageContext , checker ) ;
390
400
}
391
401
392
402
export function inferTypeForParametersFromReferences ( references : ReadonlyArray < Identifier > , declaration : FunctionLikeDeclaration , program : Program , cancellationToken : CancellationToken ) : ParameterInference [ ] | undefined {
393
403
const checker = program . getTypeChecker ( ) ;
394
404
if ( references . length === 0 ) {
395
405
return undefined ;
396
406
}
397
-
398
407
if ( ! declaration . parameters ) {
399
408
return undefined ;
400
409
}
@@ -414,10 +423,8 @@ namespace ts.codefix {
414
423
if ( callContext . argumentTypes . length <= parameterIndex ) {
415
424
isOptional = isInJSFile ( declaration ) ;
416
425
types . push ( checker . getUndefinedType ( ) ) ;
417
- continue ;
418
426
}
419
-
420
- if ( isRest ) {
427
+ else if ( isRest ) {
421
428
for ( let i = parameterIndex ; i < callContext . argumentTypes . length ; i ++ ) {
422
429
types . push ( checker . getBaseTypeOfLiteralType ( callContext . argumentTypes [ i ] ) ) ;
423
430
}
@@ -426,10 +433,10 @@ namespace ts.codefix {
426
433
types . push ( checker . getBaseTypeOfLiteralType ( callContext . argumentTypes [ parameterIndex ] ) ) ;
427
434
}
428
435
}
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 ) ) ;
432
438
}
439
+ const type = unifyFromContext ( types , checker ) ;
433
440
return {
434
441
type : isRest ? checker . createArrayType ( type ) : type ,
435
442
isOptional : isOptional && ! isRest ,
@@ -667,7 +674,7 @@ namespace ts.codefix {
667
674
}
668
675
}
669
676
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 {
671
678
if ( ! inferences . length ) return fallback ;
672
679
const hasNonVacuousType = inferences . some ( i => ! ( i . flags & ( TypeFlags . Any | TypeFlags . Void ) ) ) ;
673
680
const hasNonVacuousNonAnonymousType = inferences . some (
0 commit comments