@@ -234,9 +234,7 @@ namespace ts.codefix {
234
234
235
235
if ( renameInfo ) {
236
236
const type = checker . getTypeAtLocation ( node ) ;
237
- if ( type ) {
238
- originalType . set ( getNodeId ( clone ) . toString ( ) , type ) ;
239
- }
237
+ originalType . set ( getNodeId ( clone ) . toString ( ) , type ) ;
240
238
}
241
239
}
242
240
@@ -391,9 +389,14 @@ namespace ts.codefix {
391
389
return [ createReturn ( getSynthesizedDeepClone ( node ) ) ] ;
392
390
}
393
391
394
- function createVariableDeclarationOrAssignment ( prevArgName : SynthIdentifier , rightHandSide : Expression , transformer : Transformer ) : NodeArray < Statement > {
392
+ function createVariableDeclarationOrAssignment ( prevArgName : SynthIdentifier | undefined , rightHandSide : Expression , transformer : Transformer ) : NodeArray < Statement > {
393
+ if ( ! prevArgName || prevArgName . identifier . text . length === 0 ) {
394
+ // if there's no argName to assign to, there still might be side effects
395
+ return createNodeArray ( [ createStatement ( rightHandSide ) ] ) ;
396
+ }
395
397
396
398
if ( prevArgName . types . length < prevArgName . numberOfAssignmentsOriginal ) {
399
+ // if the variable has already been declared, we don't need "let" or "const"
397
400
return createNodeArray ( [ createStatement ( createAssignment ( getSynthesizedDeepClone ( prevArgName . identifier ) , rightHandSide ) ) ] ) ;
398
401
}
399
402
@@ -404,29 +407,32 @@ namespace ts.codefix {
404
407
// should be kept up to date with isFixablePromiseArgument in suggestionDiagnostics.ts
405
408
function getTransformationBody ( func : Node , prevArgName : SynthIdentifier | undefined , argName : SynthIdentifier , parent : CallExpression , transformer : Transformer ) : NodeArray < Statement > {
406
409
407
- const hasPrevArgName = prevArgName && prevArgName . identifier . text . length > 0 ;
408
410
const hasArgName = argName && argName . identifier . text . length > 0 ;
409
411
const shouldReturn = transformer . setOfExpressionsToReturn . get ( getNodeId ( parent ) . toString ( ) ) ;
410
412
switch ( func . kind ) {
411
413
case SyntaxKind . NullKeyword :
412
414
// do not produce a transformed statement for a null argument
413
415
break ;
414
- case SyntaxKind . Identifier :
415
- // identifier includes undefined
416
+ case SyntaxKind . Identifier : // identifier includes undefined
416
417
if ( ! hasArgName ) break ;
417
418
418
419
const synthCall = createCall ( getSynthesizedDeepClone ( func ) as Identifier , /*typeArguments*/ undefined , [ argName . identifier ] ) ;
419
420
if ( shouldReturn ) {
420
421
return createNodeArray ( [ createReturn ( synthCall ) ] ) ;
421
422
}
422
423
423
- if ( ! hasPrevArgName ) break ;
424
-
425
- const type = transformer . originalTypeMap . get ( getNodeId ( func ) . toString ( ) ) ;
426
- const callSignatures = type && transformer . checker . getSignaturesOfType ( type , SignatureKind . Call ) ;
427
- const returnType = callSignatures && callSignatures [ 0 ] . getReturnType ( ) ;
428
- const varDeclOrAssignment = createVariableDeclarationOrAssignment ( prevArgName ! , createAwait ( synthCall ) , transformer ) ;
429
- prevArgName ! . types . push ( returnType ! ) ;
424
+ const type = transformer . originalTypeMap . get ( getNodeId ( func ) . toString ( ) ) || transformer . checker . getTypeAtLocation ( func ) ;
425
+ const callSignatures = transformer . checker . getSignaturesOfType ( type , SignatureKind . Call ) ;
426
+ if ( ! callSignatures . length ) {
427
+ // if identifier in handler has no call signatures, it's invalid
428
+ codeActionSucceeded = false ;
429
+ break ;
430
+ }
431
+ const returnType = callSignatures [ 0 ] . getReturnType ( ) ;
432
+ const varDeclOrAssignment = createVariableDeclarationOrAssignment ( prevArgName , createAwait ( synthCall ) , transformer ) ;
433
+ if ( prevArgName ) {
434
+ prevArgName . types . push ( returnType ) ;
435
+ }
430
436
return varDeclOrAssignment ;
431
437
432
438
case SyntaxKind . FunctionDeclaration :
@@ -462,19 +468,21 @@ namespace ts.codefix {
462
468
return createNodeArray ( innerCbBody ) ;
463
469
}
464
470
465
- if ( hasPrevArgName && ! shouldReturn ) {
471
+ if ( ! shouldReturn ) {
466
472
const type = transformer . checker . getTypeAtLocation ( func ) ;
467
473
const returnType = getLastCallSignature ( type , transformer . checker ) ! . getReturnType ( ) ;
468
- const varDeclOrAssignment = createVariableDeclarationOrAssignment ( prevArgName ! , getSynthesizedDeepClone ( funcBody ) as Expression , transformer ) ;
469
- prevArgName ! . types . push ( returnType ) ;
474
+ const varDeclOrAssignment = createVariableDeclarationOrAssignment ( prevArgName , getSynthesizedDeepClone ( funcBody ) as Expression , transformer ) ;
475
+ if ( prevArgName ) {
476
+ prevArgName . types . push ( returnType ) ;
477
+ }
470
478
return varDeclOrAssignment ;
471
479
}
472
480
else {
473
481
return createNodeArray ( [ createReturn ( getSynthesizedDeepClone ( funcBody ) as Expression ) ] ) ;
474
482
}
475
483
}
476
484
default :
477
- // We 've found a transformation body we don't know how to handle, so the refactoring should no-op to avoid deleting code.
485
+ // If no cases apply, we 've found a transformation body we don't know how to handle, so the refactoring should no-op to avoid deleting code.
478
486
codeActionSucceeded = false ;
479
487
break ;
480
488
}
0 commit comments