TypeScript工具类型实战:条件类型与infer在业务建模中的应用

很多项目引入TypeScript后只停留在写interface和用any兜底,类型系统的表达能力没有发挥出来。工具类型和条件类型用好了,API响应、表单状态这类重复模式可以收敛成一处定义,字段调整时编译器直接指出所有需要改动的位置。按内置工具类型、条件类型、业务建模三个层次展开。

内置工具类型组合:从基础模型衍生新类型

interface User {
  id: number
  name: string
  email: string
  password: string
  createdAt: Date
}

// 对外展示视图:剔除敏感字段
type PublicUser = Omit

// 编辑表单:部分字段可选
type UserUpdateInput = Partial>

// 创建入参:去掉服务端生成的字段
type CreateUserInput = Omit

// 按字段类型映射:批量生成校验函数签名
type UserValidators = {
  [K in keyof User]: (value: User[K]) => boolean
}

基础模型变更时,衍生类型自动跟着变,不需要同步维护多份定义。

条件类型与infer:类型层面的逻辑推导

// 提取Promise的返回类型
type Unwrap = T extends Promise ? U : T
type R = Unwrap>  // string

// 提取数组元素类型
type ElementOf = T extends (infer E)[] ? E : never
type Item = ElementOf   // string

// 提取函数参数元组
type ParamsOf = T extends (...args: infer P) => any ? P : never

// 从接口包装中解出data类型
type ApiResponse = { code: number; data: T; message: string }
type DataOf = T extends ApiResponse ? D : never

条件类型配合泛型约束,可以让请求封装自动推导返回值类型,调用处不需要手动标注:

declare function request(url: string): Promise>;

const res = await request(".../orders/1");
// res.data 自动推导为 Order

API响应统一建模:分页与列表泛型

interface PageResult {
  list: T[]
  total: number
  page: number
  pageSize: number
}

type OrderPage = PageResult<{
  orderId: string
  amount: number
  status: "paid" | "pending" | "closed"
}>

// 状态字段收窄为字面量联合,switch分支自动穷尽检查
function renderStatus(s: OrderPage["list"][number]["status"]) {
  switch (s) {
    case "paid": return "已支付"
    case "pending": return "待支付"
    case "closed": return "已关闭"
    default: {
      const _exhaustive: never = s
      return _exhaustive
    }
  }
}

default分支的never赋值是穷尽检查技巧:后端新增状态值时如果漏了case,编译直接报错,比运行时发现少处理一种状态要早得多。

判别联合类型:状态机的类型安全表达

type RequestState =
  | { status: "idle" }
  | { status: "loading" }
  | { status: "success"; data: T }
  | { status: "error"; message: string }

function handle(state: RequestState) {
  if (state.status === "success") {
    console.log(state.data.list)  // 只有success分支能访问data
  }
}

判别联合比”data可能为null”加一堆可选标记的类型安全得多,每个状态下可用的属性被精确约束。

类型复杂度的边界:可读性优先

三层以上的嵌套条件类型会明显降低团队协作效率,类型体操的价值在于减少运行时错误,不是炫技。判断标准:这个类型省掉的运行时判断和维护成本,是否大于读懂它的成本。业务代码优先组合内置工具类型表达,条件类型保留给请求封装、状态机这类真正的通用抽象,其余场景写简单类型加注释更划算。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/typescript-gong-ju-lei-xing-shi-zhan-tiao-jian-lei-xing-yu/

(0)
小编小编
上一篇 22小时前
下一篇 22小时前

相关推荐