TypeScript中用对象字面量初始化含方法的类为何报错?
TypeScript类实例化的类型匹配问题
核心差异:结构类型 vs 名义类型
C#用的是名义类型系统——判断一个对象是不是某个类的实例,只看它是不是用new 类名()创建的,和结构无关。但TypeScript用的是结构类型系统——判断对象是否匹配某个类型,只看它的结构(属性、方法)是否完全对应,不管它是怎么创建的。
你的代码为什么报错
你写的{height: 10, width: 10}是普通对象字面量,它只有height和width两个属性,而你定义的Rectangle类还包含getArea方法。TS的结构类型检查要求,只要你声明变量是Rectangle类型,这个对象必须拥有Rectangle的所有成员(包括方法),所以编译器会报错说缺getArea。
当你移除getArea方法后,Rectangle类的结构就只剩height和width,和你写的对象字面量完全匹配,自然就能通过编译。
正确的实例化方式
要创建Rectangle类的实例,必须用new Rectangle()调用构造函数,而不是直接写对象字面量:
// 先修复构造函数的错误:把length改成height class Rectangle{ height: number; width: number; constructor(height: number, width: number) { this.height = height; // 这里之前写错成length了 this.width = width; } getArea(): number{ // 优化:不用传参,直接用实例自身的属性 return this.height * this.width; } } // 正确实例化 let [item1, item2]: Rectangle[] = [ new Rectangle(10, 10), new Rectangle(11, 15) ];
补充:为什么移除getArea就正常
因为此时Rectangle类的结构和你写的对象字面量完全一致,TS的结构类型检查认为两者匹配,所以允许赋值。但这其实不是真正的Rectangle实例,只是一个结构相同的普通对象,它不会继承Rectangle的任何方法(当然你已经移除了),这和C#里的类实例是完全不同的概念。
内容的提问来源于stack exchange,提问作者Georgia Red T6
相关产品推荐
相关产品推荐

