如何解决通过泛型进行类型安全递归?
我正在尝试找到一种使用泛型对递归(最后返回一个数字)进行类型安全的方法。
我尝试了什么:
function recursion<N,T>(value:N,lim:N):T|N {
if(value < lim) return recursion<N,T>(value+1,lim);
return value;
}
recursion<number,Function>(0,10);
尽管传递了 number
类型,Typescript 还是决定给我一个错误:
TSError: ⨯ Unable to compile TypeScript:
src/main.ts:2:41 - error TS2365: Operator '+' cannot be applied to types 'N' and 'number'.
2 if(value < lim) return recursion<N,lim);
我认为只要我在泛型上传递 number
类型就可以进行操作,但似乎并非如此。为什么会这样,是否有任何可能的解决方法?
尝试过(不起作用):
return recursion<number,Function>(value+1,lim)
日志:
src/main.ts:2:53 - error TS2365: Operator '+' cannot be applied to types 'N' and 'number'.
2 if(value < lim) return recursion<number,lim);
~~~~~~~
src/main.ts:2:61 - error TS2345: Argument of type 'N' is not assignable to parameter of type 'number'.
2 if(value < lim) return recursion<number,lim);
解决方法
function recursion<N,T>(value:N,lim:N): T | N {
if(value < lim) return recursion<N,T>(value+1,lim);
return value;
}
这是为什么?
recursion
接受两个泛型,可能有也可能没有在其上定义的 +
运算符。看到这个签名,似乎您可以将 value
作为参数传递给任何东西(如对象)。如果 Typescript 允许这样做,则不会导致预期的行为。
此外,您知道在您的情况下,您(最终)将返回值的类型。因此,我们知道 T
,它属于 N
类型,因为这就是递归的终止条件。
如何解决?
// 1. Make sure value has compatible type
function recursion<N extends number>(value: N,lim: N): N {
if (value < lim) {
// 2. Downcast to N
return recursion((value + 1) as N,lim);
}
return value;
}
-
我们需要确保操作符处理类型。我们在
<
和+
上应用value
和lim
运算符,因此,我们需要确保 value 和 lim 是兼容的类型。因此,我们需要确保 N 和 T 支持这些操作,因此从number
扩展(您可以使用 union 类型添加更多类型)。 -
+
运算符返回一个数字,该数字可能与N
不兼容。因此,我们需要将其显式转换为 N 以兼容递归调用。 -
我们还应该明确地告诉返回类型,函数最终会返回,所以返回的是
N
而不是函数。
老实说,对于这个确切的问题,我认为使用泛型是一种矫枉过正。我宁愿坚持使用实际类型。 Like this
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。