面试题答案
一键面试- 是否可行:
- 在TypeScript中,将
dog
直接赋值给Animal
类型的变量是可行的。
- 在TypeScript中,将
- 原因:
- TypeScript采用的是结构性类型系统(structural type system),而不是名义类型系统(nominal type system)。在结构性类型系统中,只要对象的形状(shape,即拥有的属性和属性类型)与接口兼容,就可以进行赋值。
dog
对象包含name
属性且类型为字符串,age
属性且类型为数字,满足Animal
接口的定义,尽管dog
对象还额外有breed
属性,但这并不影响它与Animal
接口的兼容性。
- TypeScript采用的是结构性类型系统(structural type system),而不是名义类型系统(nominal type system)。在结构性类型系统中,只要对象的形状(shape,即拥有的属性和属性类型)与接口兼容,就可以进行赋值。
- TypeScript类型兼容性处理规则:
- 属性兼容性:对于赋值操作,目标类型(这里是
Animal
接口)所要求的属性,源类型(这里是dog
对象的类型)必须包含,且类型一致。源类型可以有额外的属性,这不会导致类型不兼容。例如,接口interface A { x: number; }
,对象const b = { x: 1, y: 'extra' };
,b
可以赋值给A
类型的变量。 - 函数参数兼容性:在函数参数的类型兼容性中,实参的类型必须是形参类型的子类型。例如,函数
function f(a: { x: number; }){}
,调用f({ x: 1, y: 'extra' });
是可行的,因为实参对象满足形参对象类型对x
属性的要求。但反过来,如果函数function g(a: { x: number; y: string; }){}
,调用g({ x: 1 });
是不行的,因为实参对象缺少形参对象要求的y
属性。
- 属性兼容性:对于赋值操作,目标类型(这里是
示例代码如下:
interface Animal {
name: string;
age: number;
}
const dog = { name: 'Buddy', age: 3, breed: 'Labrador' };
let animal: Animal = dog; // 可行