Почему я могу установить значение свойства getter в Typescript? - PullRequest
0 голосов
/ 25 апреля 2018

Наличие класса со свойством только для геттеров:

class Person {
  sureName: string = "";
  lastName: string = "";
  get name() {
    return `${this.sureName} ${this.lastName}`;
  }
}

Мне нравится компактный C # способ инициализации вещей (например, string[] array = { "a1", "b1", "c1" };, который также возможен в Typescript. Но используя этот короткий типизированный синтаксис, я вынужден установить свойство name:

let p: Person = {
  name: "xyz",
  sureName: "a",
  lastName: "b"
};
console.log(p); // { name: 'xyz', sureName: 'a', lastName: 'b' }

Модификатор геттера, похоже, полностью игнорируется! Почему происходит это странное поведение? Это не тот случай, когда используется оператор new:

let p1 = new Person();
p1.name = "Peter"; // error TS2540: Cannot assign to 'name' because it is a constant or a read-only property.

Здесь метод получения корректно проверен с точки зрения ООП. Но по сравнению с первым мне не очень нравится new operator: у меня нет осмысленности при установке всех обязательных полей, и мне всегда приходится вводить имя объекта в качестве префикса (p1.xyz), что раздражает, когда приходится устанавливать несколько свойств на именованных объектах.

Но из-за чистого ООП я вынужден использовать синтаксис new. Или прекратите использовать C #, как getter / setter, и используйте методы, такие как getName().

1 Ответ

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

Получатель не игнорируется, он существует, если вы создаете экземпляр класса.Создание экземпляра Person означает использование оператора new (т. Е. new Person()).Вы можете проверить тот факт, что вы на самом деле не создаете Person, используя оператор instanceof

let p: Person = {
  name: "xyz",
  sureName: "a",
  lastName: "b"
};
console.log(p instanceof Person); // will be false

То, что вы делаете, - это создание литерала объекта (не экземпляра Person), которыйимеет ту же форму, что и Person.И поскольку он должен иметь одинаковую форму (то есть одинаковые открытые члены), он также должен иметь свойство name.Typescript использует структурную типизацию, поэтому это разрешено.См. Этот ответ для получения более подробной информации.

Если вы хотите создать новый Person и использовать литеральный синтаксис objet для задания значений полей, вы можете создать конструктор с помощью Partial<Person>аргумент:

 class Person {
    constructor(value: Partial<Person>) {
        Object.assign(this, value);
    }
    sureName: string = "";
    lastName: string = "";
    get name() {
        return `${this.sureName} ${this.lastName}`;
    }
}

var p = new Person({
    sureName: "a",
    lastName: "b"
})
...