TypeScript中whoWins函数返回值报错:如何正确返回指定类型值
TypeScript函数返回值错误修复:forEach回调return不生效问题
问题说明
编写whoWins()函数时声明了返回类型为{ player1Score: number; player2Score: number; message: string },但TypeScript报错:"A function whose declared type is neither 'void' nor 'any' must return a value"。核心原因是仅在forEach循环的回调函数内执行return,外层函数未返回任何值,导致TS推断函数为void类型,与声明的返回类型冲突。
解决思路
forEach的回调里的return只会终止当前回调迭代,无法将值返回给外层的whoWins函数。需要改用能中断循环并返回值的方法,比如find方法、for...of循环,或者手动遍历并在外层返回结果。
方案1:使用find定位匹配规则后返回结果
find会遍历数组,找到第一个符合条件的元素后停止遍历,基于找到的规则直接生成返回对象即可。
方案2:使用for...of循环遍历规则集
直接在外层循环中处理逻辑,找到匹配项后立即return结果,既能终止循环,又能将值返回给外层函数。
修正后的代码示例
方案1(基于find实现)
whoWins( player1Choice: string, player2Choice: string ): { player1Score: number; player2Score: number; message: string } { // 找到player1选择对应的规则 const matchedRule = ruleSet.find(rule => rule.choice === player1Choice); // 处理未找到规则的边界情况(根据业务需求调整) if (!matchedRule) { return { player1Score: this._player1Score, player2Score: this._player2Score, message: 'Invalid choice' }; } if (matchedRule.losesTo.includes(player2Choice)) { return { player1Score: this._player1Score, player2Score: ++this._player2Score, message: 'player2 Wins', }; } else if (matchedRule.beats.includes(player2Choice)) { return { player1Score: ++this._player1Score, player2Score: this._player2Score, message: 'player1 Wins', }; } else { return { player1Score: this._player1Score, player2Score: this._player2Score, message: 'Draw', }; } }
方案2(基于for...of实现)
whoWins( player1Choice: string, player2Choice: string ): { player1Score: number; player2Score: number; message: string } { for (const rule of ruleSet) { if (rule.choice === player1Choice) { if (rule.losesTo.includes(player2Choice)) { return { player1Score: this._player1Score, player2Score: ++this._player2Score, message: 'player2 Wins', }; } else if (rule.beats.includes(player2Choice)) { return { player1Score: ++this._player1Score, player2Score: this._player2Score, message: 'player1 Wins', }; } else { return { player1Score: this._player1Score, player2Score: this._player2Score, message: 'Draw', }; } } } // 必须处理未找到匹配规则的情况,保证所有代码路径都有返回值 return { player1Score: this._player1Score, player2Score: this._player2Score, message: 'Invalid choice' }; }
额外注意事项
- 必须处理未找到匹配规则的边界情况,否则TS仍会报错(因为存在无返回值的代码路径)。
forEach的设计目的是遍历执行副作用,不适合用于需要返回结果的场景,避免在这类场景中使用它。
内容的提问来源于stack exchange,提问作者Exodus Reed
相关产品推荐
相关产品推荐

