Создайте абстрактный класс с методами, возвращающими экземпляр this - PullRequest
1 голос
/ 27 апреля 2020

Я пытаюсь создать абстрактный класс ParseContent, который позволяет его разработчикам реализовывать метод parse, суть в том, что абстрактный класс ParseContent имеет другие методы, которые возвращают экземпляры наследующего класса. это возможно?

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)
  }
}

1 Ответ

1 голос
/ 27 апреля 2020

Поскольку вы используете new this в своих static членах, они будут создавать экземпляры любого класса, к которому они обращаются. Например, вызовы JSONContent.fromPath(...) (JSONContent наследуют его от ParseContent, поскольку ParseContent является прототипом JSONContent - функция, довольно точно определяющая c до JavaScript и TypeScript), создаст JSONContent экземпляр, потому что во время вызова fromPath, this равен JSONContent. Он будет использовать parse на JSONContent по той же причине: this is JSONContent.

Пример:

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

Вы можете дать подклассам возможность переопределить это с помощью вида (и, вероятно, других), но мое понимание того, что вы спрашиваете, что вы хотите поведение по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...