Home > Mobile >  Type confusion with inherited classes
Type confusion with inherited classes

Time:08-04

I have two pairs of classes that generally represent a generic oauth implementation and an SDK and then a platform specific implementation of those...

abstract class PlatformSDK {
  public abstract method1();

  // more
}

class GooglePlatformSDK extends PlatformSDK {
  // implements method defined on abstract class
  public method1() { 
    // does stuff
  }

  // new method defined only on this class
  public method2() { 
    // does different stuff
  }
}

abstract class OAuthHandler {
  public sdk: PlatformSDK;

  // does more stuff
}

class GoogleOAuthHandler extends OAuthHandler {
  constructor() {
    this.sdk = new GooglePlatformSDK();
  }

  // more...
}

This all looks great. But I get a compilation error when I instantiate the GoogleOAuthHandler and try to access the GooglePlatformSDK.method2() method:

const gh = new GoogleOAuthHandler();
gh.sdk.method2();

>> Error: Property 'method2' does not exist on type 'PlatformSDK'

Any help?

CodePudding user response:

The type of the sdk property of GoogleOAuthHandler is PlatformSDK, as inherited from the OAuthHandler superclass. Just because you initialize it with an instance of GooglePlatformSDK doesn't change that. If you want the type to be narrower in the subclass, you need to annotate it as such. Assuming the runtime code acts how you want it, you can use the declare property modifier to narrow the type of sdk property to GooglePlatformSDK without changing the generated JavaScript:

class GoogleOAuthHandler extends OAuthHandler {
    declare sdk: GooglePlatformSDK; // <-- here

    constructor() {
        super()
        this.sdk = new GooglePlatformSDK();
    }    
}

Now things should behave as you like:

const gh = new GoogleOAuthHandler();
gh.sdk.method2(); // okay

Playground link to code

  • Related