Reputation: 59345
I am trying to create an abstract class ParseContent
that allows it's implementors to implement a parse
method, the catch is that the ParseContent
abstract class has other methods, that return instances of the inheriting class. is this possible?
export abstract class ParseContent extends RawContent {
parsed: any
constructor(params: ConstructorParameters<typeof RawContent>[0] & {
parsed: any
}) {
super(params)
this.parsed = params.parsed
}
abstract parse<T> (content: string): T
static fromString(opt: Parameters<typeof RawContent['fromString']>[0]) {
const pureOpts = super.fromStringOpts(opt)
const parsed = this.parse(pureOpts.content)
return new this({ ...pureOpts, parsed })
}
static async fromPath(opt: Parameters<typeof RawContent['fromPath']>[0]) {
const pureOpts = await super.fromPathOpts(opt)
const parsed = this.parse(pureOpts.content)
return new this({ ...pureOpts, parsed })
}
}
export class JSONContent extends ParseContent {
static parse(content: string): any {
return JSON.parse(content)
}
}
Upvotes: 1
Views: 179
Reputation: 1074148
Because you're using new this
in your static
members, they'll create instances of whatever class they're called on. For instance, calls to JSONContent.fromPath(...)
(JSONContent
inherits it from ParseContent
, since ParseContent
is the prototype of JSONContent
— a feature fairly specific to JavaScript and TypeScript) will create a JSONContent
instance, because during the call to fromPath
, this
is JSONContent
. It will use the parse
on JSONContent
for the same reason: this
is JSONContent
.
Example:
class Parent {
static wrapper() {
return this.create();
}
static create() {
const ctor = (this && this[Symbol.species]) || this;
return new ctor();
}
}
class Child extends Parent {
}
console.log(Child.create() instanceof Child); // true
console.log(Child.wrapper() instanceof Child); // true
You can give subclasses the ability to override that with the species pattern (and probably others), but my sense of what you're asking is that you want the default behavior.
As for the TypeScript aspect of this, I'm afraid the news may not be good.
Upvotes: 1