【问题标题】:Why can I set the value of a getter property in Typescript?为什么我可以在 Typescript 中设置 getter 属性的值?
【发布时间】:2018-10-06 01:02:16
【问题描述】:

拥有一个只有 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() 这样的方法。

【问题讨论】:

  • 当您输入 let p: Person = ... 时,您使用的是 Person 作为 type,它(如果您检查它)不知道 getter / setter 或实现全部。它不是名为Personclass 的实例。 Person 类的所有实例都是Person 类型的值,但并非Person 类型的所有值都是Person 类的实例。

标签: class typescript getter


【解决方案1】:

getter 不会被忽略,如果您创建类的实例,它就会存在。创建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 的实例)。由于它必须具有相同的形状(即相同的公共成员),它还必须具有name 属性。 Typescript 使用结构类型,因此这是允许的。有关详细信息,请参阅此answer

如果您想创建一个新的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"
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    • 2011-07-24
    • 2012-09-22
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多