TypeScript改写JavaScript坐标移动函数遇类型错误求解
TypeScript中reduce累加器类型错误的原因与解决方法
问题描述
我有一个可正常运行的JavaScript函数:
function solve(strArr) { return strArr.reduce(function ([x, y], curr) { switch (curr) { case 'up': return [x, y + 1] case 'down': return [x, y - 1] case 'left': return [x - 1, y] case 'right': return [x + 1, y] } }, [0, 0]) }
尝试改写为TypeScript版本:
function solve(strArr: string[]): number[] { return strArr.reduce(([x, y]: number[], curr: string) => { switch (curr) { case 'up': return [x, y + 1] case 'down': return [x, y - 1] case 'left': return [x - 1, y] case 'right': return [x + 1, y] } }, [0,0]) }
但出现错误:Type 'string' is not assignable to type 'number[]',我知道错误和累加器有关,但不知道怎么解决。有人建议把strArr的类型改成any能解决,但我想用特定类型string[],这是为什么?
错误原因与解决方法
报错根源
TypeScript对reduce的泛型类型推断出现了歧义:
- 初始值
[0,0]虽会被推断为number[],但仅在回调函数里标注[x,y]: number[],并没有明确告诉TS这就是整个reduce流程中累加器的固定类型。 - 由于
strArr被标注为string[],TS会尝试对齐累加器类型与数组元素类型,最终导致类型不匹配的冲突。
两种可行的修复方式
- 明确指定
reduce的泛型参数
直接给reduce加上<number[]>,强制指定累加器的类型为number[],避免推断混乱:
function solve(strArr: string[]): number[] { return strArr.reduce<number[]>(([x, y], curr) => { switch (curr) { case 'up': return [x, y + 1] case 'down': return [x, y - 1] case 'left': return [x - 1, y] case 'right': return [x + 1, y] default: return [x, y]; // 补充default分支,规避无返回值的类型风险 } }, [0, 0]) }
- 给初始值标注类型
给初始值[0,0]加上类型断言,明确其为number[],让TS以此为基准推断累加器类型:
function solve(strArr: string[]): number[] { return strArr.reduce(([x, y], curr) => { switch (curr) { case 'up': return [x, y + 1] case 'down': return [x, y - 1] case 'left': return [x - 1, y] case 'right': return [x + 1, y] default: return [x, y]; } }, [0, 0] as number[]) }
为什么any能临时解决问题?
把strArr改成any[]后,TS会关闭对该数组的类型校验,reduce的类型推断会完全依赖初始值和回调返回值,自然不会出现类型冲突,但这等于放弃了TypeScript的类型安全特性,不建议使用。
内容的提问来源于stack exchange,提问作者Bobby Wan-Kenobi
相关产品推荐
相关产品推荐

