@@ -183,12 +183,12 @@ export class TSHelper {
183183 }
184184 }
185185
186- public static isInTupleReturnFunction ( node : ts . Node , checker : ts . TypeChecker , program : ts . Program ) : boolean {
186+ public static isInTupleReturnFunction ( node : ts . Node , checker : ts . TypeChecker ) : boolean {
187187 const declaration = TSHelper . findFirstNodeAbove ( node , ts . isFunctionLike ) ;
188188 if ( declaration ) {
189189 let functionType : ts . Type ;
190190 if ( ts . isFunctionExpression ( declaration ) || ts . isArrowFunction ( declaration ) ) {
191- functionType = TSHelper . inferAssignedType ( declaration , checker , program ) ;
191+ functionType = TSHelper . inferAssignedType ( declaration , checker ) ;
192192 } else {
193193 functionType = checker . getTypeAtLocation ( declaration ) ;
194194 }
@@ -453,99 +453,8 @@ export class TSHelper {
453453 ) !== undefined ;
454454 }
455455
456- public static inferAssignedType ( expression : ts . Expression , checker : ts . TypeChecker , program : ts . Program ) : ts . Type {
457- if ( ts . isParenthesizedExpression ( expression . parent ) ) {
458- // Ignore expressions wrapped in parenthesis
459- return this . inferAssignedType ( expression . parent , checker , program ) ;
460-
461- } else if ( ts . isCallOrNewExpression ( expression . parent ) ) {
462- // Expression being passed as argument to a function
463- const argumentIndex = expression . parent . arguments . indexOf ( expression ) ;
464- if ( argumentIndex >= 0 ) {
465- const parentSignature = checker . getResolvedSignature ( expression . parent ) ;
466- if ( parentSignature . parameters . length > 0 ) { // In case function type is 'any'
467- const signatureIndex = Math . min ( argumentIndex , parentSignature . parameters . length - 1 ) ;
468- let parameterType = checker . getTypeOfSymbolAtLocation (
469- parentSignature . parameters [ signatureIndex ] ,
470- expression
471- ) ;
472- if ( TSHelper . isArrayType ( parameterType , checker , program ) ) {
473- // Check for elipses argument
474- const parentSignatureDeclaration = parentSignature . getDeclaration ( ) ;
475- if ( parentSignatureDeclaration ) {
476- let declarationIndex = signatureIndex ;
477- if ( this . getExplicitThisParameter ( parentSignatureDeclaration ) ) {
478- // Ignore 'this' parameter
479- ++ declarationIndex ;
480- }
481- const parameterDeclaration = parentSignatureDeclaration . parameters [ declarationIndex ] ;
482- if ( ( parameterType . flags & ts . TypeFlags . Object ) !== 0
483- && ( ( parameterType as ts . ObjectType ) . objectFlags & ts . ObjectFlags . Reference ) !== 0
484- && parameterDeclaration . dotDotDotToken )
485- {
486- // Determine type from elipsis array/tuple type
487- const parameterTypeReference = ( parameterType as ts . TypeReference ) ;
488- parameterType = parameterTypeReference . typeArguments [ argumentIndex - declarationIndex ] ;
489- }
490- }
491- }
492- return parameterType ;
493- }
494- }
495-
496- } else if ( ts . isReturnStatement ( expression . parent ) ) {
497- // Expression being returned from a function
498- return this . getContainingFunctionReturnType ( expression . parent , checker ) ;
499-
500- } else if ( ts . isPropertyDeclaration ( expression . parent ) ) {
501- // Expression being assigned to a class property
502- return checker . getTypeAtLocation ( expression . parent ) ;
503-
504- } else if ( ts . isPropertyAssignment ( expression . parent ) ) {
505- // Expression being assigned to an object literal property
506- const objType = this . inferAssignedType ( expression . parent . parent , checker , program ) ;
507- const property = objType . getProperty ( expression . parent . name . getText ( ) ) ;
508- if ( ! property ) {
509- const stringPropertyType = objType . getStringIndexType ( ) ;
510- if ( stringPropertyType ) {
511- return stringPropertyType ;
512- }
513- } else {
514- return checker . getTypeAtLocation ( property . valueDeclaration ) ;
515- }
516-
517- } else if ( ts . isArrayLiteralExpression ( expression . parent ) ) {
518- // Expression in an array literal
519- const arrayType = this . inferAssignedType ( expression . parent , checker , program ) ;
520- if ( ts . isTupleTypeNode ( checker . typeToTypeNode ( arrayType ) ) ) {
521- // Tuples
522- const i = expression . parent . elements . indexOf ( expression ) ;
523- const elementType = ( arrayType as ts . TypeReference ) . typeArguments [ i ] ;
524- return elementType ;
525- } else {
526- // Standard arrays
527- return arrayType . getNumberIndexType ( ) ;
528- }
529-
530- } else if ( ts . isVariableDeclaration ( expression . parent ) ) {
531- // Expression assigned to declaration
532- return checker . getTypeAtLocation ( expression . parent . name ) ;
533-
534- } else if ( ts . isBinaryExpression ( expression . parent ) ) {
535- if ( expression . parent . operatorToken . kind === ts . SyntaxKind . EqualsToken ) {
536- // Expression assigned to variable
537- return checker . getTypeAtLocation ( expression . parent . left ) ;
538- } else {
539- // Other binary expressions
540- return TSHelper . inferAssignedType ( expression . parent , checker , program ) ;
541- }
542-
543- } else if ( ts . isAssertionExpression ( expression . parent ) ) {
544- // Expression being cast
545- return checker . getTypeFromTypeNode ( expression . parent . type ) ;
546- }
547-
548- return checker . getTypeAtLocation ( expression ) ;
456+ public static inferAssignedType ( expression : ts . Expression , checker : ts . TypeChecker ) : ts . Type {
457+ return checker . getContextualType ( expression ) || checker . getTypeAtLocation ( expression ) ;
549458 }
550459
551460 public static getAllCallSignatures ( type : ts . Type ) : ReadonlyArray < ts . Signature > {
@@ -557,8 +466,7 @@ export class TSHelper {
557466
558467 public static getSignatureDeclarations (
559468 signatures : ReadonlyArray < ts . Signature > ,
560- checker : ts . TypeChecker ,
561- program : ts . Program
469+ checker : ts . TypeChecker
562470 ) : ts . SignatureDeclaration [ ]
563471 {
564472 const signatureDeclarations : ts . SignatureDeclaration [ ] = [ ] ;
@@ -568,7 +476,7 @@ export class TSHelper {
568476 && ! TSHelper . getExplicitThisParameter ( signatureDeclaration ) )
569477 {
570478 // Infer type of function expressions/arrow functions
571- const inferredType = TSHelper . inferAssignedType ( signatureDeclaration , checker , program ) ;
479+ const inferredType = TSHelper . inferAssignedType ( signatureDeclaration , checker ) ;
572480 if ( inferredType ) {
573481 const inferredSignatures = TSHelper . getAllCallSignatures ( inferredType ) ;
574482 if ( inferredSignatures . length > 0 ) {
@@ -658,22 +566,22 @@ export class TSHelper {
658566 return contexts . reduce ( reducer , ContextType . None ) ;
659567 }
660568
661- public static getFunctionContextType ( type : ts . Type , checker : ts . TypeChecker , program : ts . Program ) : ContextType {
569+ public static getFunctionContextType ( type : ts . Type , checker : ts . TypeChecker ) : ContextType {
662570 if ( type . isTypeParameter ( ) ) {
663571 type = type . getConstraint ( ) || type ;
664572 }
665573
666574 if ( type . isUnion ( ) ) {
667575 return TSHelper . reduceContextTypes (
668- type . types . map ( t => TSHelper . getFunctionContextType ( t , checker , program ) )
576+ type . types . map ( t => TSHelper . getFunctionContextType ( t , checker ) )
669577 ) ;
670578 }
671579
672580 const signatures = checker . getSignaturesOfType ( type , ts . SignatureKind . Call ) ;
673581 if ( signatures . length === 0 ) {
674582 return ContextType . None ;
675583 }
676- const signatureDeclarations = TSHelper . getSignatureDeclarations ( signatures , checker , program ) ;
584+ const signatureDeclarations = TSHelper . getSignatureDeclarations ( signatures , checker ) ;
677585 return TSHelper . reduceContextTypes (
678586 signatureDeclarations . map ( s => TSHelper . getDeclarationContextType ( s , checker ) ) ) ;
679587 }
0 commit comments