This is very simple example of what I want to get. My question is about @returns tag. What should I write there?
class Base{
/**
* @returns {QUESTION: WHAT SHOUL BE HIRE??}
*/
static method(){
return new this()
}
}
class Sub extends Base{
}
let base= Base.method() // IDE should understand that base is instance of Base
let sub= Sub.method() // IDE should understand that sub is instance of Sub
I know that this is a very old question and that in most circumstances projects needing a polymorphic this for static methods would now be using TypeScript with the workaround as listed here.
Several of our browser based projects are still using pure ES module JavaScript without any build step and introducing a build step for this use case seems over the top. On these projects we are also using Visual Studio Code's 'Implicit Project Config: Check JS' to enable type checking. Having to cast the return of every extended static method is a real pain!
The following workaround works well in Visual Studio Code for JavaScript with JSDoc:

/**
* @template T
* @param {T} Class
* @returns {{
* method: () => InstanceType<T>
* } & T}
*/
// @ts-ignore
const fixPolymorphicThis = Class => Class
class Base {
static method() {
return new this()
}
}
const Sub = fixPolymorphicThis(class Sub extends Base { })
let base = Base.method() // IDE should understand that base is instance of Base
let sub = Sub.method() // IDE should understand that sub is instance of Sub
console.assert(sub instanceof Base)
console.assert(sub instanceof Sub)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With