为何在TypeScript中能为仅含getter的属性赋值?
为什么TypeScript中能给只有getter的属性赋值?
这个问题的核心其实是TypeScript结构类型系统和JavaScript类实例化机制的差异导致的,我来帮你拆解清楚:
1. 你的代码里的p并不是Person类的实例
你用对象字面量{ name: "xyz", sureName: "a", lastName: "b" }赋值给Person类型变量时,创建的只是一个普通JavaScript对象,而非Person类的实例——你没有使用new Person()来触发类的构造函数,自然也不会继承类里的get name()逻辑。
2. TypeScript的结构类型检查允许这种赋值
TypeScript是基于结构类型来判断兼容性的:只要一个对象的属性类型和目标类型的属性类型匹配,就可以赋值给该类型的变量。
对于Person类,TypeScript会把get name()推断为一个只读的string类型属性,你的对象字面量里的name是string类型,加上sureName和lastName也符合类型要求,所以TypeScript不会阻止这个赋值操作。
3. 运行时的本质差异
- 普通对象的
name是一个直接定义的可写属性,和Person类的getter没有任何关系,所以你设置的"xyz"会直接成为这个属性的值。 - 如果你创建真正的
Person实例,情况就完全不同了:
此时class Person { sureName: string = ""; lastName: string = ""; get name() { return `${this.sureName} ${this.lastName}`; } } // 正确创建类实例 let p = new Person(); p.sureName = "a"; p.lastName = "b"; console.log(p.name); // 输出 "a b" // p.name = "xyz"; // 编译时会报错,运行时也会抛出错误(因为没有setter)p是Person的实例,name是类定义的getter属性,无法直接赋值,只能通过修改sureName和lastName来改变它的返回值。
总结
你之所以能设置name属性,是因为你操作的不是Person类的实例,只是一个结构匹配的普通对象。如果想使用类的getter逻辑,必须用new Person()来创建实例,此时TypeScript会在编译时阻止你给name赋值,运行时也会报错。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

