TS 类型系统支持尾递归优化了,拿下面这个例子就好理解:
type TrimLeft<T extends string> = T extends ` ${infer Rest}` ? TrimLeft<Rest> : T; // error: Type instantiation is excessively deep and possibly infinite. type Test = TrimLeft<" oops">;
在没有做尾递归优化前,TS 会因为堆栈过深而报错,但现在可以正确返回执行结果了,因为尾递归优化后,不会形成逐渐加深的调用,而是执行完后立即退出当前函数,堆栈数量始终保持不变。
JS 目前还没有做到自动尾递归优化,但可以通过自定义函数 TCO 模拟实现,下面放出这个函数的实现:
function tco(f) { var value; var active = false; var accumulated = []; return function accumulator(...rest) { accumulated.push(rest); if (!active) { active = true; while (accumulated.length) { value = f.apply(this, accumulated.shift()); } active = false; return value; } }; }
核心是把递归变成 while 循环,这样就不会产生堆栈。