как установить переменные-члены typescript, которые неизвестны в конструкторе

Я изучаю Typescript и хочу знать, как правильно определять переменные-члены класса.

На данный момент я объявляю их в классе над конструктором, но чтобы убедиться, что они созданы в конструкторе (или я получаю предупреждение), я объявляю их как любой тип | нулевой. Это означает, что если я могу затем создать экземпляр переменной-члена в конструкторе, установив ее равной нулю, а затем установив ее правильное значение, когда я смогу.

Я не знаю, правильный ли это способ объявления переменных-членов. Например :

export default class FlowerBed {
  canv:HTMLCanvasElement | null;
  ctx:CanvasRenderingContext2D | null;
  p2d:Path2D;
  t:number;
  currentPoint:Array<number>;
  to:number = 0;
  image:HTMLImageElement | null;
  imagesrc:CanvasImageSource | null;
  pattern:CanvasPattern | null;

  constructor (garden:HTMLCanvasElement) {
    this.image = null;
    this.imagesrc = null;
    this.canv = null;
    this.ctx = null;
    this.pattern = null;
    this.to = 0;
    this.p2d = new Path2D();
    this.t = 0;
    this.currentPoint = [160,350];  
  }

У меня нет значения холста, ctx, шаблона и т. д. во время строительства.

Есть ли более правильный способ действий?

Большое спасибо...


person miller the gorilla    schedule 27.03.2020    source источник
comment
Используете ли вы null в особом значении? Я имею в виду, есть ли разница в вашем коде, если вы замените эти null на undefined?   -  person Shlang    schedule 27.03.2020
comment
Итак, у меня было бы image:HTMLImageElement | undefined и this.image = undefined в конструкторе? Думаю, что Undefined лучше, чем null, семантически это имеет больше смысла.   -  person miller the gorilla    schedule 27.03.2020
comment
Однако многие компоненты React выставляют свои переменные как объединения с нулевым значением, которых я должен придерживаться в определениях параметров...   -  person miller the gorilla    schedule 27.03.2020
comment
React использует null со специальным значением, например, вы должны вернуть null в качестве результата рендеринга, иначе это будет считаться ошибкой. Это способ сделать вещи менее подверженными ошибкам, которые могут быть чрезмерными, если вы используете другие инструменты, такие как TypeScript.   -  person Shlang    schedule 27.03.2020


Ответы (1)


Поэтому, если вам не нужно использовать null со специальным значением, вы можете упростить свой класс.

export default class FlowerBed {
  canv?: HTMLCanvasElement;
  ctx?: CanvasRenderingContext2D;
  p2d: Path2D = new Path2D();
  t: number = 0;
  currentPoint: Array<number> = [160, 350];
  to: number = 0;
  image?: HTMLImageElement;
  imagesrc?: CanvasImageSource;
  pattern?: CanvasPattern;

  constructor(garden: HTMLCanvasElement) {
    // ...
  }

  someMethod() {
    // Note the exclamation mark – it tells ts you are sure the property has a value
    return this.canv!.getBoundingClientRect();
  }
}

? после имени поля означает, что поле может отсутствовать, что почти равнозначно его наличию undefined. В зависимости от вашего опыта вы можете предпочесть присваивать значения конструктору, но вы все же можете избежать здесь нулевых присваиваний.

Стоит отметить, что в объекте отсутствуют неинициализированные свойства, поэтому проверки во время выполнения, такие как hasOwnProperty, возвращают false.

const fb = new FlowerBed(canvasEl);
fb.hasOwnProperty('ctx'); // false

Поэтому, если это важно, вы можете инициализировать их, но не обязательно делать это в конструкторе.

export default class FlowerBed {
  canv?: HTMLCanvasElement;
  ctx?: CanvasRenderingContext2D = undefined;
  // ...
}

Это может быть полезно, когда есть случай, когда свойство может получить некоторое нулевое значение во время выполнения, и это одна из причин, по которой некоторые разработчики различают значения undefined и null, используя undefined как «еще не инициализированный», а null как «пустой или не- существующая стоимость"

person Shlang    schedule 27.03.2020
comment
Мне нужно инициализировать неизвестные переменные как неопределенные в конструкторе, чтобы использовать ключевое слово this, но это нормально. Большое спасибо. - person miller the gorilla; 29.03.2020