《TypeScript 高级类型实战指南:解决真实项目的 7 大痛点》

目录标题

  • 本文解决的问题:
  • 一、表单系统:深度类型约束(可直接用于 Ant Design 表单)
    • 痛点:表单校验逻辑与 TS 类型脱节
  • 二、API 响应:自动解包层叠类型(Axios 拦截器整合)
    • 痛点:后端返回结构嵌套导致类型冗余
  • 三、Redux Toolkit:Action 类型自动工厂
    • 痛点:手写 Action Type 容易出错
  • 四、组件 Prop:动态约束联合类型(Vue/React 通用)
    • 痛点:多形态组件的 Prop 类型难以维护
  • 五、配置系统:智能提示与防御(适用低代码平台)
    • 痛点:配置对象无法获得类型提示
  • 六、性能优化:大型项目类型加速方案
    • 技巧 1:类型缓存避免重复计算
    • 技巧 2:类型作用域隔离

本文解决的问题:

表单验证类型混乱 | API 响应类型膨胀 | Redux Action 自动推断
配置项智能提示 | 组件 Prop 动态约束 | ⚡ 类型性能优化 | 第三方库类型扩展

一、表单系统:深度类型约束(可直接用于 Ant Design 表单)

痛点:表单校验逻辑与 TS 类型脱节

// 实现:表单规则与类型系统联动
type FieldType<T> = {
  [K in keyof T]: {
    value: T[K]
    rules?: Array<{
      required?: boolean
      validator?: (val: T[K]) => string | void
    }>
  }
}

// 使用示例(自动推断name为string,age为number)
const userForm: FieldType<{
  name: string
  age: number
}> = {
  name: {
    value: '',
    rules: [{ 
      validator: (val) => val.length < 2 && '至少2位' 
    }]
  },
  age: {
    value: 0,
    rules: [{ required: true }]
  }
}

效果:提交时自动获得强类型数据,校验错误精准定位字段

二、API 响应:自动解包层叠类型(Axios 拦截器整合)

痛点:后端返回结构嵌套导致类型冗余

// 实现:自动提取真实数据层
type UnwrapAPIResponse<T> = 
  T extends { data: { result: infer U } } ? U :
  T extends { data: infer U } ? U : never

// 声明增强后的axios实例
declare const api: {
  get<T>(url: string): Promise<UnwrapAPIResponse<T>>
}

// 使用示例
interface RealData {
  items: Array<{ id: number; name: string }>
}

// 直接获取最终数据,无需手动解包
const data = await api.get<{ data: { result: RealData } }>('/list') 
// data类型自动推断为 RealData

三、Redux Toolkit:Action 类型自动工厂

痛点:手写 Action Type 容易出错

// 实现:根据slice自动生成Action类型
type ActionMap<Slice> = {
  [K in keyof Slice]: Slice[K] extends (...args: any[]) => infer R 
    ? R extends { payload: infer P } 
      ? (payload: P) => { type: K; payload: P }
      : () => { type: K }
    : never
}

// 使用示例
const userSlice = {
  login: (state: any, payload: { token: string }) => {},
  logout: (state: any) => {}
}

type UserActions = ReturnType<ActionMap<typeof userSlice>[keyof ActionMap<typeof userSlice>]>

// 生成结果:
// { type: 'login', payload: { token: string } } | { type: 'logout' }

四、组件 Prop:动态约束联合类型(Vue/React 通用)

痛点:多形态组件的 Prop 类型难以维护

// 实现:根据type动态约束其他prop
type ButtonProps = {
  type: 'primary' | 'dashed'
} & ({
  type: 'primary'
  icon: string
} | {
  type: 'dashed'
  dashedStyle: 'solid' | 'dotted'
})

// 测试用例
const props1: ButtonProps = {
  type: 'primary',
  icon: 'add' // 必须存在
}

const props2: ButtonProps = {
  type: 'dashed',
  dashedStyle: 'dotted' // 必须存在
}

五、配置系统:智能提示与防御(适用低代码平台)

痛点:配置对象无法获得类型提示

// 实现:配置项自动提示+类型校验
type StrictConfig<T> = {
  readonly [K in keyof T]: {
    label: string
    defaultValue: T[K]
    options?: T[K] extends string ? string[] : never
  }
}

// 使用示例
const config: StrictConfig<{
  theme: 'light' | 'dark'
  fontSize: number
}> = {
  theme: {
    label: '主题',
    defaultValue: 'light',
    options: ['light', 'dark'] // 自动提示
  },
  fontSize: {
    label: '字号',
    defaultValue: 14
    // 若添加options会报错,因为fontSize是number
  }
}

六、性能优化:大型项目类型加速方案

技巧 1:类型缓存避免重复计算

// 使用工具类型缓存中间结果
type Memoize<T> = T extends (...args: infer A) => infer R 
  ? (...args: A) => R & { __cache?: Map<string, R> }
  : never

// 应用示例
declare function heavyCompute<T>(input: T): SomeComplexType<T>
const cachedCompute: Memoize<typeof heavyCompute> = heavyCompute

技巧 2:类型作用域隔离

// 使用namespace隔离类型污染
declare namespace ApiTypes {
  export type User = { id: string }
  export type Post = { title: string }
}

// 使用时明确作用域,避免全局类型冲突
const user: ApiTypes.User = { id: '1' }

到这里,这篇文章就和大家说再见啦!我的主页里还藏着很多 篇 Vue 实战干货,感兴趣的话可以点击头像看看,说不定能找到你需要的解决方案~
创作这篇内容花了很多的功夫。如果它帮你解决了问题,或者带来了启发,欢迎:
点个赞❤️ 让更多人看到优质内容
关注「前端极客探险家」 每周解锁新技巧
收藏文章⭐️ 方便随时查阅
特别提醒:
转载请注明原文链接,商业合作请私信联系
感谢你的阅读!我们下篇文章再见~

《TypeScript 高级类型实战指南:解决真实项目的 7 大痛点》_第1张图片

你可能感兴趣的:(typescript,前端,vue.js,react.js)