Можно ли получить доступ к свойству прототипа класса? - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть вопрос, но я не знаю, есть ли правильные слова, чтобы задать его в одной фразе. Я пишу свой код на TypeScript и хочу добиться следующего:

Я получил абстрактный класс «Ресурс»

// Resource.ts
abstract class Resource {
  public abstract readonly type: string;
  protected _id?: string;

  get id() {
    return this._id;
  }

  public static info() {
    return {
      type: this.prototype.type
    };
  }
}

и, скажем, класс ресурсов Post, который наследует из абстрактного класса

class PostResource extends Resource {
  public readonly type = 'post'
}

Я хочу получить доступ к свойству "type" из прототипа класса PostResource, как я пытался сделать с помощью метода Resource.info() stati c. Очевидно, он возвращает undefined.

Я также пытался создать экземпляр класса внутри метода stati c следующим образом

public static info() {
  return {
    type: (new this()).type
  }
}

, но выдает ошибку, потому что я не могу создать экземпляр Ресурс как абстрактный класс.

Я также пытался использовать свойства stati c:

abstract class Resource {
  public static readonly type: string;

  public static info() {
    return {
      type: this.type
    }
  }
}

class PostResource extends Resource {
  public static readonly type = 'post';
}

Это теоретически работает, но тогда я теряю все преимущества наследования, потому что stati c свойства и методы не могут быть абстрактными. Например, я мог бы создать PostResource без свойства type stati c, и TypeScript не предупредит меня. type тогда будет undefined, что не очень хорошо, потому что все классы с расширенными ресурсами должны иметь свойство type.

Поэтому я ищу решение, позволяющее мне получить доступ ко всем инициализированным свойствам в классе с расширенными ресурсами.

Я надеюсь, что мой вопрос ясен, спасибо за вашу помощь!

РЕДАКТИРОВАТЬ:

Я должен дать более подробную информацию о моей конечной цели. Я хотел бы иметь список классов, которые наследуют абстрактный класс Resource, и, следовательно, имеют свойство "type". В идеале это должно быть свойство stati c, потому что я мог бы просто перебирать классы и просто получать доступ к свойству. Но мне также нужно это значение внутри экземпляров этого класса, поэтому, например, у меня может быть что-то вроде этого:

console.log(PostResource.type); // > 'post'
const post1 = new PostResource();
console.log(post1.type); // > 'post';

Ответы [ 2 ]

0 голосов
/ 25 апреля 2020

На самом деле ваша попытка создания экземпляра класса внутри метода stati c может сработать, вам просто нужно правильно набрать this:

public static info(this: new () => Resource) {
  return {
    type: new this().type
  }
}

Playground

Подробнее об аннотации параметра this функции.

0 голосов
/ 25 апреля 2020

Как насчет наличия свойства _type в абстрактном классе и его инициализации в конструкторе подклассов?

abstract class Resource {

  protected _type: string;

  constructor(type: string) {
    this._type = type;
  }

  public info() {
    return {
      type: this._type
    }
  }
}

class PostResource extends Resource {
  constructor() {
    super('post');
  }
}

class GetResource extends Resource {
  constructor() {
    super('get');
  }
}

let postResource = new PostResource();
let getResource = new GetResource();

console.log(postResource.info()); // {type: 'post'}
console.log(getResource.info()); // {type: 'get'}

Edit

Я не уверен, что вы пытаетесь достичь, но вот пример для ваших обновленных требований:

abstract class Resource {

}

class PostResource extends Resource {
  static type = 'post';
  public type = 'post';
}

let postResource = new PostResource();

console.log(PostResource.type); // post
const post1 = new PostResource();
console.log(post1.type); // post
...