Home > Mobile >  How can I type the instance of an untyped class?
How can I type the instance of an untyped class?

Time:08-04

I am extending a class which comes from an external library and is sadly not typed. To makes matters even more complicated, it's instantiation is done via a static method in the untyped class. The change of this as it stands is not an option. It would look something like this:

class MyUntypedClass {
  constructor (context) {
    this.someAttribute = ''
    this.someOtherAttribute = ''
  }

  static createNewInstanceWithStuff () {
    // do a bunch of stuff prior to creating the instance
    const instance = new this(context)

    return instance
  }
}

As mentioned I then extend it and make sure to type my methods:


class MyTypedClass extends MyUntypedClass {
  private myNewAttribute = ''

  constructor() {
    super({ stuff })
    this.myNewAttribute = myNewAttribute
  }

  private myNewMethod (param: string, otherParam: number): string {
    // do stuff
  }
}

However, I must instantiate it via the static method from MyUntypedClass, and I end up losing the types I had written for my methods. Code looks something like this:

const instance = MyTypedClass.createNewInstanceWithStuff()

const value = instance.myNewMethod('some string', 123) // if I try to check  the params or return type it is any

Is there anyway to type my methods whenever the instance is created from the untyped parent class?

CodePudding user response:

If you want the static createNewInstanceWithStuff method of MyTypedClass to be of a more specific type than that of the MyUntypedClass but you don't want to change the runtime behavior, you can use the declare property modifier to tell the compiler that. This will have no effect on the emitted JavaScript. It looks like this:

class MyTypedClass extends MyUntypedClass {
  /* ... */    
  declare static createNewInstanceWithStuff: () => MyTypedClass; // <-- declare this
  /* ... */
}

Note that you have to use a function-typed field annotation instead of a method, because the declare property modifier is not currently supported for methods (see microsoft/TypeScript#38008 for the relevant feature request).

Now it should work as expected:

const instance = MyTypedClass.createNewInstanceWithStuff();
// const instance: MyTypedClass
const value = instance.myNewMethod('some string', 123) 
// const value: string;

Playground link to code

  • Related