MST

星途 面试题库

面试题:TypeScript 接口的基本使用及类型兼容性

请定义一个接口 `UserInfo`,包含属性 `name`(字符串类型)、`age`(数字类型)和 `email`(字符串类型,可选)。然后定义一个函数 `printUser`,接受一个符合 `UserInfo` 接口的对象作为参数,并在函数内部打印出用户信息。另外,解释一下 TypeScript 中接口类型兼容性的规则。
12.4万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
interface UserInfo {
  name: string;
  age: number;
  email?: string;
}

function printUser(user: UserInfo) {
  let info = `Name: ${user.name}, Age: ${user.age}`;
  if (user.email) {
    info += `, Email: ${user.email}`;
  }
  console.log(info);
}

TypeScript 中接口类型兼容性规则

  1. 属性少的类型兼容属性多的类型:如果一个类型的属性是另一个类型属性的子集,那么这个类型是兼容的。例如:
interface A {
  x: number;
}
interface B {
  x: number;
  y: number;
}
let a: A = { x: 1 };
let b: B = { x: 1, y: 2 };
a = b; // 允许,因为 B 的属性包含 A 的所有属性
// b = a; // 不允许,因为 A 缺少 B 中的 y 属性
  1. 可选属性与兼容:可选属性在兼容性判断时会被忽略。例如:
interface C {
  x: number;
  y?: number;
}
interface D {
  x: number;
}
let c: C = { x: 1 };
let d: D = { x: 1 };
c = d; // 允许,y 是可选属性,在兼容性判断时被忽略
d = c; // 也允许,因为 D 中没有 y 属性,而 C 的 y 属性是可选的
  1. 函数参数的双向协变:在函数类型兼容性判断时,参数类型是双向协变的。即参数类型更宽松或者更严格的函数类型都可能是兼容的。例如:
let func1 = (x: number) => x;
let func2 = (x: any) => x;
func1 = func2; // 允许,因为 any 类型比 number 类型更宽松
func2 = func1; // 也允许,因为 number 类型比 any 类型更严格
  1. 函数返回值的协变:函数返回值类型是协变的,即返回值类型更具体(更严格)的函数类型是兼容返回值类型更宽泛(更宽松)的函数类型。例如:
let func3 = () => ({ name: 'John' });
let func4 = () => ({ name: 'John', age: 30 });
func3 = func4; // 允许,因为 func4 的返回值类型是 func3 返回值类型的超集
// func4 = func3; // 不允许,因为 func3 的返回值类型缺少 func4 返回值中的 age 属性