TypeScript实现支持类型推断的Get/Set元组函数参数
解决方案:关联Get/Set函数的类型推断
你的核心问题是原实现中TypeScript无法反向推断泛型T的类型,导致setter的参数类型丢失。我们可以通过明确关联单个Get/Set对的类型,再基于值类型元组生成对应的参数类型来解决这个问题。
步骤1:定义单个Get/Set对的类型
先创建一个类型,强制让get函数的返回值类型和set函数的参数类型保持一致:
type GetSetPair<V> = readonly [ get: (index: number) => V, set: (index: number) => (value: V) => void ];
步骤2:定义值类型元组到Get/Set对元组的映射
通过映射类型,将一组值类型的元组转换为对应的Get/Set对元组:
type GetSetTuple<V extends readonly any[]> = { [I in keyof V]: GetSetPair<V[I]>; };
步骤3:实现类型安全的createGetSet函数
让函数泛型接收值类型元组,参数使用映射后的Get/Set对元组,TypeScript会自动推断每个值类型并关联到对应Get/Set函数:
const createGetSet = <V extends readonly any[]>(arg: GetSetTuple<V>) => {};
验证效果
用你的测试代码验证,此时setter的value参数会自动和getter的返回类型关联:
type DataItem = { readonly id: number; readonly value: string; }; const data: DataItem[] = []; createGetSet([ [ (i) => data[i], (i) => (value) => { data[i] = value; // value被正确推断为DataItem }, ], [ (i) => data[i]?.value, (i) => (value) => { if (data[i]) data[i].value = value; // value被正确推断为string }, ] ]);
为什么原实现失败?
你最初的Arg<T>类型是从泛型T映射到Get/Set对,但TypeScript无法从Arg<T>反向推断T的具体类型(存在循环依赖),导致setter的参数类型退化为any。而新方案是先让TypeScript推断值类型元组V,再生成对应的Get/Set对,避免了推断循环。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

