跳到主要内容
← 返回文章列表
面试题-基础2026/08/11约 2 分钟读完

面试题:TypeScript 异步状态建模与穷尽检查

本题考察你能否用 TypeScript 准确表达业务状态,并利用类型系统减少运行时错误。

面试题:TypeScript 异步状态建模与穷尽检查
文章目录 3

题目

下面的异步请求状态存在什么问题?

interface User {
  id: number;
  name: string;
}

interface UserState {
  loading: boolean;
  data?: User;
  error?: string;
}

请重新设计 UserState,满足以下要求:

  1. 支持 idle、loading、success、error 四种状态。

  2. success 状态一定有 data。

  3. error 状态一定有错误信息。

  4. 实现 renderUser(state),并让 TypeScript 在遗漏状态分支时能够报错。

题解

原设计的问题是:loading、data、error 相互独立,能够表示业务上不合理的状态,例如请求成功却没有 data。

可以使用可辨识联合类型:

interface User {
  id: number;
  name: string;
}

type UserState =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'success'; data: User }
  | { status: 'error'; error: string };

实现渲染和穷尽检查:

function renderUser(state: UserState): string {
  switch (state.status) {
    case 'idle':
      return '尚未加载';

    case 'loading':
      return '加载中';

    case 'success':
      return `用户:${state.data.name}`;

    case 'error':
      return `加载失败:${state.error}`;

    default: {
      const exhaustiveCheck: never = state;
      return exhaustiveCheck;
    }
  }
}

核心原理:

  • status 是判别字段,TypeScript 会根据它自动收窄类型。

  • success 状态一定存在 data。

  • error 状态一定存在 error。

  • 新增状态但忘记处理时,never 穷尽检查会产生编译错误。

面试时的推荐表达

可以这样回答:

原来的 loading、data 和 error 是相互独立的字段,可以组成很多业务上不合法的状态。单独增加 status 也不够,因为 success 仍然不能保证存在 data。我会使用以 status 为判别字段的联合类型,让每种状态携带自己的数据。处理状态时,TypeScript 可以根据 status 自动收窄类型;再通过 never 进行穷尽检查,使新增状态但遗漏处理逻辑时能够在编译阶段报错。如果多个接口具有相同状态结构,还可以抽成 AsyncState<T, E> 泛型。

评论

0 条

评论会在审核后展示,邮箱不会公开。

正在确认登录状态

5000 / 5000