类型“ ObjectConstructor”上不存在属性“ entries”


76

我正在研究ng2实现。我正在使用以下函数调用将对象转换为数组:

var authors = Object.entries(responseObject.Authors);

这是一个标准的js函数。但是,ts编译器返回以下错误:

"Property 'entries' does not exist on type 'ObjectConstructor'"

根据一个快速的谷歌,似乎解决方案可能是将CompilerOptions target属性从es5更改为es6。但是,在对以前的问题进行了一些先前的研究之后,我认为我可以通过在下面的tsconfig.json中包含其他“ lib”属性来利用es6功能:

  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "module": "commonjs",
    "noEmitOnError": true,
    "noImplicitAny": false,
    "outDir": "../Scripts/",
    "removeComments": false,
    "sourceMap": true,
    "target": "es5",
    "moduleResolution": "node",
    "lib": [
      "es2015",
      "dom"
    ]
  }

我也尝试将target属性更改为es2015,然后重建项目并执行“ typescriptUsingTsConfig”,但仍然遇到相同的错误。知道我可以在这里做什么以利用Object.entries()函数吗?

Answers:


126

您很正确地认为,更改target是错误的方法,而更改lib是正确的方法,但是您指定的语言版本错误。根据MDNObject.entries已正式添加到ES2017规范中。

"lib": ["es2017"]

因此,您必须指定*。

如果希望为ES2017Object添加的函数方法添加声明,则TypeScript允许您指定更细的值

"lib": ["es2017.object"]

正如亚历山大·伯德(Alexander Bird)所指出的,默认情况下,"lib"选项的隐式值取决于为其指定的值("target"如果存在)。

例如:

"target": "es2017"

将导致"lib.*"默认情况下包含相应的前缀,除非"lib"明确指定。

请注意,您可能希望添加实现本身的polyfill,例如this,以确保此方法在较旧的运行时中有效。

注意:作为替代,您可以指定任何更高版本

"lib": ["es2020"]

甚至自然

"lib": ["esnext"] 

最后一个将包括TypeScript语言已知的最新标准库功能的声明。由于它代表一个移动的目标,因此应谨慎使用此选项,因为根据定义,对所有相应的运行时进行polyfill定义是一项复杂的任务,需要进行研究,并且可能取决于目标运行时来加载不同的polyfill。

此外,该"lib"选项的数组性质允许您组合多个值以匹配您的运行时。例如,要匹配支持es2015的Web浏览器并添加由polyfill提供的这些对象方法,您可以编写

"lib": ["es2015", "es2017.object", "dom"]

有关其他详细信息,请参见《TypeScript手册》。

注意: 一些评论者问为什么更改将是错误的,--target而不是--lib因为两者都将使代码能够进行检查?原因是--target改变了代码的编译方式。例如,这"target": "es2017"意味着async对于较旧的运行时不会转换功能。这是不正确的,因为其意图是允许使用其他库,而不是更改输出语法,因此区分语法特征和库特征非常重要。


1
@ user8334943否,您肯定不需要IE 10的polyfill。MDN链接的底部具有浏览器支持信息。
阿兰·哈达德

1
其他注意事项:如果您尚未使用lib编译器选项,则可能有基于您的目标的默认值,在您设置时将被覆盖lib。有关默认列表,请参见编译器选项文档。我必须lib为我的目标显式添加默认参数es2017.object
alexanderbird'9

1
@AluanHaddad可以肯定:)我同意保持更新尽可能长,我将尽快执行更新。这是一个大型应用程序,有许多开发人员,因此需要计划更新。感谢您的输入!
Jessy

1
为什么更新lib而不是更新更正确target
rjh

1
@rjh Target更改代码的编译方式。例如,这"target": "es2017"意味着async对于较旧的运行时不会转换功能。这是不正确的,因为其目的是允许使用其他库,而不是更改输出语法。
Aluan Haddad '18

11

接受的答案对我不起作用,但是我改写了属性“ assign”中的答案,该类型不存在于“ ObjectConstructor”类型上,如下所示:

const changedFields = (<any>Object).entries(this.ngForm.form.controls)
                                   .filter(value => value[1].dirty);

与处境相同的人分享


2
谢谢Nguyen ......我正在将Angular 6和打字稿2.6.2一起使用,这对我来说是有用的。我希望有人能解释一下。
MichaelE

在打字稿游乐场为我工作。那是一些严重的巫毒
朱利安·萨格特

在打字稿游乐场中,您目前无法设置,--lib因此必须使用隐式--target指定--lib
Aluan Haddad

你是英雄 我不能更改该库,因为它是由另一个我无法更改tsconfig的应用程序生成的。
DavidFariña20年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.