是否可以访问类原型的属性?

时间:2020-04-25 10:24:58

标签: javascript typescript class abstract-class

我有一个问题,但我不知道用一个词就能问到正确的词。 我正在用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'
}

我想从PostResource类原型访问“ type”属性,就像我尝试使用Resource.info()静态方法那样。显然,它返回undefined

我也试图实例化静态方法中的类

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

但是它抛出一个错误,因为我不能实例化Resource,因为它是一个抽象类。

我也尝试使用静态属性:

abstract class Resource {
  public static readonly type: string;

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

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

理论上可行,但随后我放弃了继承的所有好处,因为静态属性和方法不能抽象化。例如,我可以创建一个没有type静态属性的PostResource,而TypeScript不会警告我。 type将是undefined,这不好,因为所有Resource-extended类都应具有type属性。

因此,我正在寻找一种解决方案,以允许我访问在Resource-extended类中初始化的所有属性。

我希望我的问题很清楚,谢谢您的帮助!

编辑:

我应该提供有关我最终目标的更多细节。 我想要一个继承Resource抽象类的类列表,因此具有“ type”属性。理想情况下,它应该是静态属性,因为我可以简单地遍历类并访问该属性。 但是我也需要在此类的实例中使用此值,例如,我可以拥有类似的内容:

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

2 个答案:

答案 0 :(得分:0)

在抽象类中具有属性_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'}

编辑

我不确定您要达到的目标,但这是您更新要求的示例:

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

答案 1 :(得分:0)

实际上,您尝试在static方法中实例化类是可行的,您只需要为this输入正确的类型即可即可:

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

Playground

More info在函数的this参数注释中。