@@ -2856,20 +2856,26 @@ export class Resolver extends DiagnosticEmitter {
28562856 /** How to proceed with eventual diagnostics. */
28572857 reportMode : ReportMode = ReportMode . Report ,
28582858 /** Contextual flow. */
2859- ctxFlow ? : Flow ,
2859+ ctxFlow : Flow | null = null
28602860 ) : Function | null {
28612861 let classInstance : Class | null = null ; // if an instance method
28622862 let instanceKey = typeArguments ? typesToString ( typeArguments ) : "" ;
28632863
28642864 // Instance method prototypes are pre-bound to their concrete class as their parent
28652865 if ( prototype . is ( CommonFlags . Instance ) ) {
28662866
2867- // The actual class instance may be a subclass of the bound class in the case of
2868- // a function or property that uses the polymorphic `this` type
2867+ // The actual class instance may be a subclass of the bound class
28692868 if ( this . currentThisExpression && ctxFlow ) {
2870- let element = this . lookupExpression ( this . currentThisExpression , ctxFlow ) ;
2871- if ( element ?. kind == ElementKind . Class ) {
2872- classInstance = < Class > element ;
2869+ // In the case of a function or property that uses the polymorphic `this` type,
2870+ // this is important, so the return is typed as the actual class instance.
2871+ // Note: It should work without this outer type check, and does when testing, but fails the "bootstrap" build.
2872+ // TODO: Figure out why and remove the extra check.
2873+ let type = prototype . functionTypeNode . returnType ;
2874+ if ( type . kind == NodeKind . NamedType && ( < NamedTypeNode > type ) . name . identifier . text == CommonNames . this_ ) {
2875+ let element = this . lookupExpression ( this . currentThisExpression ! , ctxFlow ) ;
2876+ if ( element && element . kind == ElementKind . Class && element . is ( CommonFlags . Resolved ) ) {
2877+ classInstance = < Class > element ;
2878+ }
28732879 }
28742880 }
28752881
@@ -3512,7 +3518,7 @@ export class Resolver extends DiagnosticEmitter {
35123518 ) ;
35133519 break ;
35143520 }
3515- if ( boundPrototype . typeNode ? .kind == NodeKind . NamedType && ( < NamedTypeNode > boundPrototype . typeNode ) . name . identifier . text == CommonNames . this_ ) {
3521+ if ( assert ( boundPrototype . typeNode ) . kind == NodeKind . NamedType && ( < NamedTypeNode > boundPrototype . typeNode ) . name . identifier . text == CommonNames . this_ ) {
35163522 this . error (
35173523 DiagnosticCode . Not_implemented_0 ,
35183524 assert ( boundPrototype . typeNode ) . range ,
@@ -3779,7 +3785,7 @@ export class Resolver extends DiagnosticEmitter {
37793785 /** How to proceed with eventual diagnostics. */
37803786 reportMode : ReportMode = ReportMode . Report ,
37813787 /** Contextual flow. */
3782- ctxFlow ? : Flow ,
3788+ ctxFlow : Flow | null = null
37833789 ) : Property | null {
37843790 let instance = prototype . instance ;
37853791 if ( instance ) return instance ;
0 commit comments