MST

星途 面试题库

面试题:TypeScript 中 type 和 interface 在复杂类型定义及类型体操中的应用

假设要实现一个复杂的类型系统,用于处理嵌套的对象数组,其中每个对象可能有不同的属性且属性类型也较为复杂,要求使用 type 和 interface 分别进行类型定义,并阐述在这个过程中,如何利用它们各自的特性完成类型体操,以实现类型的灵活推导和约束。
17.5万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

使用 type 进行类型定义

// 定义基础类型
type Name = string;
type Age = number;

// 定义复杂属性类型
type Address = {
  street: string;
  city: string;
  zip: number;
};

// 定义对象类型
type Person = {
  name: Name;
  age: Age;
  address: Address;
  hobbies: string[];
};

// 定义嵌套的对象数组类型
type PeopleArray = Person[];

type 可以用于定义别名,它能给已有类型起一个新名字,如 NameAge,也能定义联合类型、交叉类型等复杂类型。在这个例子中,我们通过 type 定义了基础类型、复杂属性类型、对象类型以及嵌套对象数组类型。

使用 interface 进行类型定义

// 定义基础类型(这里只是为了对比,实际基础类型很少用interface)
interface NameInterface {
  value: string;
}

interface AgeInterface {
  value: number;
}

// 定义复杂属性类型
interface AddressInterface {
  street: string;
  city: string;
  zip: number;
}

// 定义对象类型
interface PersonInterface {
  name: string;
  age: number;
  address: AddressInterface;
  hobbies: string[];
}

// 定义嵌套的对象数组类型
interface PeopleArrayInterface {
  [index: number]: PersonInterface;
}

interface 主要用于定义对象的形状,它有很好的可扩展性,可以通过接口继承来扩展已有接口。例如:

interface EmployeeInterface extends PersonInterface {
  employeeId: number;
  department: string;
}

利用特性完成类型体操

  1. type 的特性利用
    • 联合类型和交叉类型:如果对象属性可能是多种类型之一,可以使用联合类型,如 type MaybeNumberOrString = number | string;。交叉类型可以用于合并多个类型的属性,如 type MergedType = { a: string } & { b: number };。在嵌套对象数组中,如果某个属性可能是不同类型对象中的属性,可以用联合类型来灵活推导。
    • 条件类型:可以使用条件类型进行类型的判断和选择,例如 type IsString<T> = T extends string? true : false;。在处理嵌套对象数组时,如果根据某个属性值来决定其他属性的类型,可以使用条件类型来实现。
  2. interface 的特性利用
    • 接口继承:通过接口继承可以很方便地复用已有接口的属性,并添加新的属性。如上面的 EmployeeInterface 继承自 PersonInterface,在处理复杂类型系统时,对于具有层次关系的对象类型,接口继承可以很好地进行类型约束和推导。
    • 索引签名:如 interface PeopleArrayInterface { [index: number]: PersonInterface; },可以定义对象数组的类型,在处理嵌套对象数组时,通过索引签名可以灵活定义数组元素的类型,同时也可以用于定义对象中属性名不确定但属性类型确定的情况。