Flow中返回受约束泛型类型的函数时无法返回包装函数如何解决?
错误原因
你定义的泛型FuncType是任意满足AnyFunction约束的子类型,Flow类型系统不会默认新创建的箭头函数和传入的FuncType完全等价:FuncType可能附带额外的类型信息,比如重载签名、函数对象附加属性、特殊的this类型约束等,新生成的箭头函数只能满足AnyFunction的基础约束,无法证明它完全匹配所有可能的FuncType子类型的要求。
你简化的示例也同理:泛型FuncType是() => number的子类型,若用户将FuncType指定为返回1 | 2字面量的函数类型,你返回的返回随机数的函数明显不符合约束,Flow会直接阻止这种可能不兼容的返回。
直接返回原函数不会报错,是因为原函数本身就是FuncType类型的实例,天然符合返回值要求。
修复方案
针对你要封装try/catch逻辑的业务需求,有两种可行的写法:
方案1:类型断言
你逻辑上可以保证包装后的函数和原函数参数、返回值、this行为完全一致的情况下,可以用类型断言直接告知Flow类型兼容:
// @flow type AnyFunction = (...args: Array<any>) => any; function wrap<FuncType: AnyFunction>(innerFunc: FuncType): FuncType { return ((...args) => { try { return innerFunc.apply(this, args); } catch (e) { // 自定义异常处理逻辑 console.error('捕获异常', e); throw e; } }: any) as FuncType; }
方案2:拆分泛型参数
不想用类型断言的话,可以把函数的参数、返回值单独抽为泛型参数,Flow可以直接推断出类型兼容:
// @flow function wrap<Args: $ReadOnlyArray<mixed>, Return>( innerFunc: (...args: Args) => Return ): (...args: Args) => Return { return (...args) => { try { return innerFunc.apply(this, args); } catch (e) { // 自定义异常处理逻辑 console.error('捕获异常', e); throw e; } }; }
这种写法不需要额外的类型断言,Flow原生支持类型校验。
内容的提问来源于stack exchange,提问作者aldel
相关产品推荐
相关产品推荐

