TypeScript:如何根据函数参数约束类型及优化useWatchProps泛型约束
TypeScript类型约束与useWatchProps实现详解
1. 如何根据函数参数约束TypeScript类型?
核心是利用泛型约束和类型自动推导实现:
- 先通过泛型约束限定类型范围,比如
O extends Record<string, any>要求O必须是键值对结构,K extends keyof O限制K只能是O的属性键; - 让函数参数关联泛型,比如
keys: T中T被约束为K | K[],这样传入的keys只能是O的单个属性键或键数组,从参数层面约束了泛型的合法范围,TypeScript会根据传入的参数自动推断泛型的具体类型。
2. 如何让useWatchProps的回调函数参数与第一个参数keys的类型一一对应?
通过自定义递归条件类型处理数组结构的keys,再结合条件判断区分单个键和数组键的场景:
- 定义
KeysToValues类型,递归遍历keys数组,将每个元素(O的属性键)映射为对应的属性值类型,最终生成与keys顺序完全一致的元组类型; - 回调参数类型通过
T extends K ? O[K] : KeysToValues<O, K>做分支判断:如果T是单个属性键,参数类型为对应属性值;如果是键数组,参数类型为对应值组成的元组,实现回调参数与keys的类型一一对应。
3. 如何通过keys约束泛型T?
在函数泛型定义中给T设置明确约束,并依赖TypeScript的泛型推导能力:
- 将T的约束设为
K | K[](K是O的属性键),确保T只能是O的单个属性键或键数组; - 当传入具体的keys参数时,TypeScript会自动推断T的具体类型(单个键类型或键元组类型),从而完成keys对泛型T的约束。
完整代码示例
type KeysToValues<O extends Record<string, any>, K> = K extends [ infer G, ...infer L ] ? G extends keyof O ? [O[G], ...KeysToValues<O, L>] : [] : [] function useWatchProps< O extends Record<string, any>, K extends keyof O = keyof O, T extends K | K[] = K | K[] >( keys: T, callback: (values: T extends K ? O[K] : KeysToValues<O, K>) => void ) {} // 单个键调用:回调参数a自动推断为number类型 useWatchProps<{ a: number; b: string }>('a', (a) => { a // number }) // 数组键调用:回调参数[a,b]自动推断为[number, string]元组 useWatchProps<{ a: number; b: string }>(['a', 'b'], ([a, b]) => { a // number b // string })
内容的提问来源于stack exchange,提问作者Link
相关产品推荐
相关产品推荐

