@@ -72,11 +72,18 @@ namespace ts.codefix {
7272 } ) ,
7373 } ) ;
7474
75+ function createObjectTypeFromLabeledExpression ( checker : TypeChecker , label : Identifier , expression : Expression ) {
76+ const member = checker . createSymbol ( SymbolFlags . Property , label . escapedText ) ;
77+ member . type = checker . getTypeAtLocation ( expression ) ;
78+ const members = createSymbolTable ( [ member ] ) ;
79+ return checker . createAnonymousType ( /*symbol*/ undefined , members , [ ] , [ ] , /*stringIndexInfo*/ undefined , /*numberIndexInfo*/ undefined ) ;
80+ }
81+
7582 function getFixInfo ( checker : TypeChecker , declaration : FunctionLikeDeclaration , expectType : Type , isFunctionType : boolean ) : Info | undefined {
7683 if ( ! declaration . body || ! isBlock ( declaration . body ) || length ( declaration . body . statements ) !== 1 ) return undefined ;
7784
7885 const firstStatement = first ( declaration . body . statements ) ;
79- if ( isExpressionStatement ( firstStatement ) && checkFixedAssignableTo ( checker , declaration , firstStatement . expression , expectType , isFunctionType ) ) {
86+ if ( isExpressionStatement ( firstStatement ) && checkFixedAssignableTo ( checker , declaration , checker . getTypeAtLocation ( firstStatement . expression ) , expectType , isFunctionType ) ) {
8087 return {
8188 declaration,
8289 kind : ProblemKind . MissingReturnStatement ,
@@ -87,7 +94,8 @@ namespace ts.codefix {
8794 }
8895 else if ( isLabeledStatement ( firstStatement ) && isExpressionStatement ( firstStatement . statement ) ) {
8996 const node = createObjectLiteral ( [ createPropertyAssignment ( firstStatement . label , firstStatement . statement . expression ) ] ) ;
90- if ( checkFixedAssignableTo ( checker , declaration , node , expectType , isFunctionType ) ) {
97+ const nodeType = createObjectTypeFromLabeledExpression ( checker , firstStatement . label , firstStatement . statement . expression ) ;
98+ if ( checkFixedAssignableTo ( checker , declaration , nodeType , expectType , isFunctionType ) ) {
9199 return isArrowFunction ( declaration ) ? {
92100 declaration,
93101 kind : ProblemKind . MissingParentheses ,
@@ -107,7 +115,8 @@ namespace ts.codefix {
107115 const firstBlockStatement = first ( firstStatement . statements ) ;
108116 if ( isLabeledStatement ( firstBlockStatement ) && isExpressionStatement ( firstBlockStatement . statement ) ) {
109117 const node = createObjectLiteral ( [ createPropertyAssignment ( firstBlockStatement . label , firstBlockStatement . statement . expression ) ] ) ;
110- if ( checkFixedAssignableTo ( checker , declaration , node , expectType , isFunctionType ) ) {
118+ const nodeType = createObjectTypeFromLabeledExpression ( checker , firstBlockStatement . label , firstBlockStatement . statement . expression ) ;
119+ if ( checkFixedAssignableTo ( checker , declaration , nodeType , expectType , isFunctionType ) ) {
111120 return {
112121 declaration,
113122 kind : ProblemKind . MissingReturnStatement ,
@@ -122,8 +131,35 @@ namespace ts.codefix {
122131 return undefined ;
123132 }
124133
125- function checkFixedAssignableTo ( checker : TypeChecker , declaration : FunctionLikeDeclaration , expr : Expression , type : Type , isFunctionType : boolean ) {
126- return checker . isTypeAssignableTo ( checker . getTypeAtLocation ( isFunctionType ? updateFunctionLikeBody ( declaration , createBlock ( [ createReturn ( expr ) ] ) ) : expr ) , type ) ;
134+ function checkFixedAssignableTo ( checker : TypeChecker , declaration : FunctionLikeDeclaration , exprType : Type , type : Type , isFunctionType : boolean ) {
135+ if ( isFunctionType ) {
136+ const sig = checker . getSignatureFromDeclaration ( declaration ) ;
137+ if ( sig ) {
138+ if ( hasModifier ( declaration , ModifierFlags . Async ) ) {
139+ exprType = checker . createPromiseType ( exprType ) ;
140+ }
141+ const newSig = checker . createSignature (
142+ declaration ,
143+ sig . typeParameters ,
144+ sig . thisParameter ,
145+ sig . parameters ,
146+ exprType ,
147+ /*typePredicate*/ undefined ,
148+ sig . minArgumentCount ,
149+ sig . flags ) ;
150+ exprType = checker . createAnonymousType (
151+ /*symbol*/ undefined ,
152+ createSymbolTable ( ) ,
153+ [ newSig ] ,
154+ [ ] ,
155+ /*stringIndexInfo*/ undefined ,
156+ /*numberIndexInfo*/ undefined ) ;
157+ }
158+ else {
159+ exprType = checker . getAnyType ( ) ;
160+ }
161+ }
162+ return checker . isTypeAssignableTo ( exprType , type ) ;
127163 }
128164
129165 function getInfo ( checker : TypeChecker , sourceFile : SourceFile , position : number , errorCode : number ) : Info | undefined {
0 commit comments