为什么我可以在 Typescript 中设置 getter 属性 的值?

Why can I set the value of a getter property in Typescript?

有一个 class 和一个 getter 只有 属性 像这样:

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' }

getter修饰符似乎被完全忽略了!为什么会发生这种奇怪的行为?使用 new 运算符时情况并非如此:

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

此处 getter 从 OOP 视图正确验证。但与第一个相比,我不太喜欢 new operator:我没有设置所有必填字段的智能感知,而且我总是必须将对象名称键入前缀 (p1.xyz),这很烦人当必须在命名明确的对象上设置多个 属性 时。

但是为了拥有干净的 OOP,我不得不使用 new 语法。或者停止使用像 getter/setter 这样的 C#,并使用像 getName().

这样的方法

getter 不会被忽略,如果您创建 class 的实例,它就会存在。创建 Person 的实例意味着使用 new 运算符(即 new Person())。您可以使用 instanceof 运算符

来测试您实际上并未创建 Person
let p: Person = {
  name: "xyz",
  sureName: "a",
  lastName: "b"
};
console.log(p instanceof Person); // will be false

你正在做的是创建一个与 Person 具有相同形状的对象文字(不是 Person 的实例)。由于它必须具有相同的形状(即相同的 public 个成员),因此它还必须具有 name 属性。 Typescript 使用结构类型,所以这是允许的。有关详细信息,请参阅此

如果您想创建一个新的 Person 并使用对象文字语法来指定字段值,您可以创建一个带有 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"
})