Set 去重出现 'downlevelIteration' 错误的解决方案
问题描述
在使用 TypeScript 和 React 开发时,当你尝试使用 [...new Set(array)]
语法来去除数组中的重复元素时,可能会遇到以下 TypeScript 错误:
Type 'Set<unknown>' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher
这个错误表示 TypeScript 编译器无法在当前配置下正确编译扩展运算符 ...
与 Set 对象结合使用的语法。
原始问题代码示例
const uniqueMuscle = workoutexercices.map((exercice: any) => {
let exercicesId = exercice.id;
exercicesId = [...new Set(exercicesId)];
return exercicesId;
});
根本原因
这个问题的根本原因是 TypeScript 的编译目标(target)设置过低。扩展运算符 ...
与 Set 对象的结合使用需要 ES2015(ES6) 或更高版本的 JavaScript 支持。
如果 tsconfig.json
中的 target
设置为 es5
或更低版本,TypeScript 无法将这种语法转换为兼容的 ES5 代码。
解决方案
方案一:修改 tsconfig.json 配置(推荐)
修改 TypeScript 配置文件,将编译目标设置为 ES2015 或更高版本:
{
"compilerOptions": {
"target": "es2015",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
// 其他配置保持不变...
}
}
TIP
es2015
和 es6
是等价的,两者都可以使用。现代项目建议使用 es2020
或 esnext
以获得最新的 JavaScript 特性支持。
方案二:使用 Array.from() 方法替代
如果不希望修改 TypeScript 配置,可以使用 Array.from()
方法来替代扩展运算符:
exercicesId = Array.from(new Set(exercicesId));
这种方法与扩展运算符效果相同,但兼容性更好,可以在较低的 ES 版本中使用。
方案三:使用 filter 方法手动去重
作为另一种替代方案,可以使用数组的 filter
方法手动实现去重功能:
exercicesId = exercicesId.filter((value, index, array) =>
array.indexOf(value) === index
);
这种方法虽然代码量稍多,但完全不依赖 Set 对象和扩展运算符,兼容性最好。
配置示例
以下是一个完整的、推荐的 tsconfig.json
配置示例:
{
"compilerOptions": {
"target": "es2020",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"jsxImportSource": "react"
},
"include": [
"src"
]
}
{
"compilerOptions": {
"target": "es5", // 可能需要修改为 es2015 或更高
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}
注意事项
WARNING
修改 target
为更高版本可能会影响代码的浏览器兼容性。请根据你的项目需求选择合适的 ES 版本。
INFO
如果使用的是 Create React App,默认的 target
是 es5
。修改为更高版本后,可能还需要将 React.Node
改为 React.ReactNode
:
// 修改前
function Component(): React.Node {}
// 修改后
function Component(): React.ReactNode {}
总结
遇到 downlevelIteration
错误时,有三种主要解决方案:
- 修改 tsconfig.json:将
target
设置为es2015
或更高版本(推荐) - 使用 Array.from():替代扩展运算符语法
- 使用 filter 方法:手动实现去重功能
根据项目需求和兼容性要求选择最适合的方案。对于新项目,建议直接使用 ES2015 或更高版本作为编译目标。