Vectrobyte
Vectrobyte

Reputation: 1475

(Typescript) Unable to access static properties from non static method and vice versa

I am designing a custom Model structure for my NodeJS project. I have created a base class named Model which is inherited by other model classes. The base model class will have a set of properties that needs to be accessed by the methods. The properties will get overwritten by child classes as shown in the examples below(by User model).

There is a table property which I need to access from both static as well as non-static methods as such:

Case 1: Base model class has non-static property table.

class Model {
  protected table = '';

  public static find(id: number) {
    // I want to have table name in here but cant.
  }

  public save() {
    // I am able to get table name in here `this`.
  }
}

class User extends Model {
  protected table = 'users'; // overwriting parent's table property

  // list of other non static properties in here

  constructor(user: UserSchema) {
    // assign non static properties from here
  }
}

Case 2: Base model class has static property table.

class Model {
  protected static table = '';

  public static find(id: number) {
    // I am able to get table name in here using `this`.
  }

  public save() {
    // I want to have table name in here but cant.
  }
}

class User extends Model {
  protected static table = 'users'; // overwriting parent's table property

  // list of other non static properties in here

  constructor(user: UserSchema) {
    // assign non static properties from here
  }
}

I tried changing the static and non-static nature of table property but whenever I switch, there occurs two scenarios.

I could access static property using class name(e.g. Model.table) but it will result base model's empty value("") and I need the User's overloaded table value('users') to work.

I want to have control over both the scenarios where I could get the properties interchangibly(accessing static property from non static method as well as static property from non static method). How can I acheive this behaviour? Any suggestion is appreciated.

Upvotes: 3

Views: 1483

Answers (1)

ford04
ford04

Reputation: 74490

Concerning Case 1:

Instance properties like table are not accessible from a static context. You would either have to make table a static protected static table = '' or let find become an instance method public find(id: number){...}.

Concerning Case 2:

table is a static class property and will be set on the constructor function of User itself. It is not related to table in Model, therefore it is not possible to override it via protected static table = 'users' in User. You can check the ES5 transpiled code to get a feeling, how static is implemented in classes.

There is an (untyped) way to get an overridden static property from parent by invoking this.constructor.table in the Model base class. But I think, what you want and what is a cleaner solution, is to make table a (possibly abstract) instance property, which provides the the child value from the parent:

class Model {
  protected table = "";

  public save() {
    console.log(this.table)
  }
}

class User extends Model {
  protected table = 'users';
}

class Developer extends Model {
  protected table = 'devs';
}
new Developer().save() // "devs"
new User().save() // "users"

sample

Upvotes: 1

Related Questions