MST

星途 面试题库

面试题:TypeScript与JavaScript类型互操作性中的类型兼容性

假设在TypeScript中有一个接口`interface Animal { name: string; age: number; }`,在JavaScript中有一个对象`const dog = { name: 'Buddy', age: 3, breed: 'Labrador' };`,将`dog`赋值给`Animal`类型的变量是否可行?如果可行,原因是什么?如果不可行,怎样修改才能使其可行,同时阐述TypeScript在这种类型兼容性处理上的规则。
15.3万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
  1. 是否可行
    • 在TypeScript中,将dog直接赋值给Animal类型的变量是可行的。
  2. 原因
    • TypeScript采用的是结构性类型系统(structural type system),而不是名义类型系统(nominal type system)。在结构性类型系统中,只要对象的形状(shape,即拥有的属性和属性类型)与接口兼容,就可以进行赋值。dog对象包含name属性且类型为字符串,age属性且类型为数字,满足Animal接口的定义,尽管dog对象还额外有breed属性,但这并不影响它与Animal接口的兼容性。
  3. 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; // 可行