首页 > 解决方案 > 为什么我可以在 Typescript 中设置 getter 属性的值?

问题描述

拥有一个只有 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.

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

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

标签: classtypescriptgetter

解决方案


getter 不会被忽略,如果您创建类的实例,它就会存在。创建实例Person意味着使用new运算符(即。new Person())。Person您可以使用instanceof运算符测试您实际上并未创建 a 的事实

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

您正在做的是创建一个对象文字(不是 的实例Person),其形状与Person. 并且由于它必须具有相同的形状(即相同的公共成员),它也必须具有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"
})

推荐阅读