表单验证类型混乱 | API 响应类型膨胀 | Redux Action 自动推断
配置项智能提示 | 组件 Prop 动态约束 | ⚡ 类型性能优化 | 第三方库类型扩展
// 实现:表单规则与类型系统联动
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 }]
}
}
效果:提交时自动获得强类型数据,校验错误精准定位字段
// 实现:自动提取真实数据层
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
// 实现:根据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' }
// 实现:根据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
}
}
// 使用工具类型缓存中间结果
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
// 使用namespace隔离类型污染
declare namespace ApiTypes {
export type User = { id: string }
export type Post = { title: string }
}
// 使用时明确作用域,避免全局类型冲突
const user: ApiTypes.User = { id: '1' }
到这里,这篇文章就和大家说再见啦!我的主页里还藏着很多 篇 Vue 实战干货,感兴趣的话可以点击头像看看,说不定能找到你需要的解决方案~
创作这篇内容花了很多的功夫。如果它帮你解决了问题,或者带来了启发,欢迎:
点个赞❤️ 让更多人看到优质内容
关注「前端极客探险家」 每周解锁新技巧
收藏文章⭐️ 方便随时查阅
特别提醒:
转载请注明原文链接,商业合作请私信联系
感谢你的阅读!我们下篇文章再见~