Typescript flatMap, flat, flatten 在任何类型上不存在 []

Posted

技术标签:

【中文标题】Typescript flatMap, flat, flatten 在任何类型上不存在 []【英文标题】:flatMap, flat, flatten doesn't exist on type any[] 【发布时间】:2019-05-02 13:01:34 【问题描述】:

我使用的是 chrome 70,并且 chrome 确实添加了方法 .flatMap, .flatten, .flat。所以我的代码确实按预期运行。不幸的是,Typescript 不喜欢它。

// data.flatMap lint error
export const transformData = (data: any[]) => data.flatMap(abc => [
   parentObj(abc),
   ...generateTasks(abc)
]);

我收到的警告是TS2339: Property 'flatMap' does not exist on type 'any[]'.

顺便说一句,我使用的是Angular 6,它使用的是Typescript ~2.9.2,并且我已经在polyfills.ts 中包含了import 'core-js/es7/array';

我的猜测是这些方法没有打字,我确实尝试过npm run -dev @types/array.prototype.flatmap但仍然没有解决。

【问题讨论】:

【参考方案1】:

您应该将es2019es2019.array 添加到您的--lib 设置中,以便TypeScript 识别array.flat()flatMap()

例子:


  "compilerOptions": 
    "target": "es5",
    "lib": [
      "es2019"
    ]
  

以前它作为 esnextesnext.array 的一部分提供,但现在它正式成为 ES2019 的一部分。

【讨论】:

是的,我复制了这个并且它有效。这是我的compilerOptions tsconfig.app.json "lib": [ "es2017", "dom", "esnext.array", ] 谢谢先生 这并没有在我的 IDE VSCode 中为我解决。有什么建议吗? @timelf123 你重启你的IDE了吗? 注意:node 11+现在支持flatMap @maninak es2019.array 在大多数情况下是首选,因为它明确指定了项目支持的 es2019 规范的功能,避免意外使用不支持的 es2019 功能【参考方案2】:

如果您的版本低于 es2019,您可以实现一个 shiv 以提供与后续库提供的 .flat().flatMap() 类似的功能。

到平面单级数组

arr.reduce((acc, val) => acc.concat(val), []);

到平面多级数组

function flatDeep(arr, d = 1) 
   return d > 0 ? arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatDeep(val, d - 1) : val), []) : arr.slice();
;

要深入了解,您也可以查看以下链接

https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/Array/flat

【讨论】:

感谢这个 sn-p — 它很有帮助,因为即使在接受的答案中使用了 Typescript 修复,我仍然无法使用 .flat() @DavidYeiser 如果这对你有帮助,也许你应该投票 :) 这个 sn-p 有帮助,因为在 tsconfig.json 中添加 "lib": ["ES2019"], 后我仍然无法让 .flat() 工作【参考方案3】:

Aaron Beall 的回答非常出色。值得知道的是,如果 tsConfig.JSON 文件中未指定“lib”,则会注入默认的库列表。注入的默认库是: ► 对于 --target ES5:DOM,ES5,ScriptHost ► 对于 --target ES6:DOM,ES6,DOM.Iterable,ScriptHost

换句话说:我们必须指定之前自动添加的那些库。 (请参阅:https://www.typescriptlang.org/docs/handbook/compiler-options.html 了解更多信息)

"compilerOptions": 

   "target": "es6",

   "lib": [ "es2019", "DOM", "ES6" ,"DOM.Iterable", "ScriptHost"],

【讨论】:

【参考方案4】:

您可以在等待稳定性的同时扩展全局数组接口,此时它将被添加到默认库中。

interface Array<T> 
    flat(): Array<T>;
    flatMap(func: (x: T) => T): Array<T>;

【讨论】:

【参考方案5】:

从 angular 11 开始,感谢 typescript 3.9,这是现在的新配置。

"compilerOptions": 
    "target": "es2018",
    "module": "es2020",
    "lib": ["es2020", "dom"],

为什么是es2020 而不是esnext

在 TypeScript 3.9 中,由模块控制的 TypeScript 编译器的行为与“esnext”和“es2020”值相同。这种行为将来可能会发生变化,因为“esnext”选项可能会以向后不兼容的方式发展,从而在 TypeScript 更新期间导致构建时或运行时错误。结果,代码可能变得不稳定。使用“es2020”选项可以降低这种风险。

for further read

【讨论】:

【参考方案6】:

您也可以将 esnext 添加到您的 --lib 而不是“es2019”

"compilerOptions": 
    "target": "es2015",
    "lib": ["dom", "esnext"]

它对我有用。

【讨论】:

【参考方案7】:

我尝试了大多数答案,但它们对我不起作用。 IDE:VScode

但确实如此

npm i -D @types/node

【讨论】:

以上是关于Typescript flatMap, flat, flatten 在任何类型上不存在 []的主要内容,如果未能解决你的问题,请参考以下文章

map 和 flatMap 区别

map 和 flatMap 区别

typescript TypeScript中的Array.prototype.flatMap方法。

使用泛型制作 Array.flat(1) 的 Typescript 包装器

ECMAScript 2019(ES10)新特性简介

2021年大数据常用语言Scala(二十三):函数式编程 扁平化映射 flatMap