TypeScript中如何组合Get与Set实例得到GetSet交叉类型?
解决TypeScript交叉类型GetSet的实例组合问题
你用get & set尝试组合交叉类型实例的方式是错误的,因为这里的&是JavaScript的按位与运算符,不是TypeScript的类型交叉操作符——它会把函数对象转换成数值运算,自然触发类型错误。
错误原因拆解
get & set会将两个函数对象强制转换为数值(通常结果是NaN或0),所以TS2362报错说算术运算的操作数类型不对;- 你把这个运算得到的数值传给
callback,但callback需要的是GetSet类型,所以TS2345报错说number类型无法赋值给GetSet。
可行解决方案
1. 类型断言(快速实现)
如果你确认运行时环境能处理函数的双重调用逻辑(比如Recoil框架的内部机制),可以直接用类型断言跳过TypeScript的检查:
function perform() { callback(get as GetSet); }
2. 重载函数(类型安全)
要严格符合类型要求,可以写一个重载函数,内部根据参数转发到对应的get或set:
const getSet: GetSet = <T>( target: RecoilValue<T> | RecoilState<T>, update?: ((currVal: T) => T) | T ): T | void => { if (update === undefined) { return get(target as RecoilValue<T>); } else { return set(target as RecoilState<T>, update); } }; function perform() { callback(getSet); }
这种方式完全通过TypeScript的类型校验,运行时也能正确处理两种调用场景。
3. 合并函数对象(利用JS特性)
JS中函数是特殊对象,用Object.assign可以把set的属性合并到get上,TypeScript会自动推断合并后的类型为Get & Set:
function perform() { const getSet = Object.assign(get, set); callback(getSet); }
注意:这种方式仅适用于两个函数没有同名属性的情况,且默认调用执行的是get的逻辑,如需执行set仍需额外处理。
4. 调整类型定义(更符合常规设计)
如果你的实际需求是传递一个包含get和set方法的对象,而非兼具两种调用签名的函数,建议修改GetSet的定义:
export type GetSet = { get: Get; set: Set; }; // 调用时直接传对象 function perform() { callback({ get, set }); }
这种设计更直观,也避免了函数交叉类型带来的混淆。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

