Переопределить тип переменной экземпляра в расширенном классе

#typescript #class #variables #inheritance #overriding

#typescript #класс #переменные #наследование #переопределение

Вопрос:

У меня есть вопрос о наследовании и типах переменных экземпляра в typescript.

Давайте представим, что у меня есть простой класс следующим образом:

 class Person {
  instanceVariable: Object;
  age: Number;

  constructor(instanceVariable: Object, age: Number) {
    this.instanceVariable = instanceVariable;
    this.age = age;
  } 
};

let alice = new Person({}, 50);  //This will work
let sarah = new Person({}, "fifty"); //Typescript will complain here..

  

Typescript выполняет то, что вы ожидаете от него здесь. Он будет жаловаться, когда вы попытаетесь создать sarah :).
Но теперь давайте представим, что у вас есть другой класс, который расширяет это, и вы хотите убедиться, что у этого класса все еще есть переменная экземпляра, но переопределяет тип.

 //Create a simple class that extends and overrides the type
class Student extends Person {
  instanceVariable: String 
}

let bvk = new Student("test", 50);  //This should work
let katie = new Student(50, 50);  //This shouldn't work

  

К сожалению, это работает не так, как ожидалось. Typescript жалуется: «Свойство’instanceVariable’ не имеет инициализатора и определенно не назначено в конструкторе».

Если вы попытаетесь добавить конструктор, я не понимаю, как заставить его работать, потому что я хочу в основном вызвать «super» для установки данных. Это тоже не работает, хотя у typescript та же жалоба!

 class Student extends Person {
  instanceVariable: String;
  constructor(instanceVariable: String, age: Number){
    super(instanceVariable, age)
  }
}

  

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

Ответ №1:

Вы могли бы использовать общий тип для своего Person класса:

 class Person<T = object> {
  instanceVariable: T;

  constructor(instanceVariable: T, age: number) {
    // ...
  } 
}
  

Ваш Student then может расширяться Person следующим образом:

 class Student extends Person<string> {}
  

PS: Взгляните на самый первый пункт о том, что делать и чего не делать