类型“ ObjectConstruction”上不存在属性“ entry”

我正在开发一个 ng2实现,我使用以下函数调用将一个对象转换为一个数组:

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

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

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

基于一个快速谷歌似乎是解决方案可能是更改了编译器选项目标属性从 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"
]
}

我还尝试将目标属性更改为 es2015,然后重新构建项目并执行“ typeescriptUsingTsConfig”,但仍然得到相同的错误。知道我在这里可以做些什么来利用 Object.entries()功能吗?

65218 次浏览

You're quite correct that changing target is the wrong approach and changing lib is the correct approach, however you have specified the wrong version of the language. According to MDN, Object.entries was officially added in the ES2017 specification.

"lib": ["es2017"]

is therefore what you must specify instead*.

If you wish to add only the declarations for the methods of the Object function that were added in ES2017, TypeScript allows you to specify a more granular value.

"lib": ["es2017.object"]

As noted by Alexander Bird, by default, the implicit value of the "lib" option is dependent on the value specified for "target" if present.

For example:

"target": "es2017"

Will cause the correspondingly prefixed "lib.*" to be included by default unless "lib" is specified explicitly.

Note that you will likely wish to add a polyfill of the implementation itself, such as the this one, to ensure this works in older runtimes.

Note: as an alternative you can specify any later version

"lib": ["es2020"]

or naturally even

"lib": ["esnext"]

This last will include the declarations for the very latest standard library features known to the TypeScript language. As it represents a moving target, this option should be used with care since polyfilling all of the corresponding runtime is by definition a complex task that will require research and may involve loading different polyfills depending on your target runtime.

Additionally, the array nature of the "lib" option allows you to combine multiple values to match your runtime. For example, to match es2015 capable web browsers with the addition of these object methods as provided by a polyfill, you can write

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

See the TypeScript Handbook for additional details.

Note: a few commenters asked why it would be wrong to change --target instead of --lib as both would enable the code to type check? The reason is that --target changes how the code is transpiled. For example, "target": "es2017" means that async functions won't be transformed for older runtimes. It is incorrect because the intent was to enable the use of additional libraries, not to change the output syntax and it is therefore important to distinguish between syntactic features and library features.

The accepted answer didn't work for me, but I adapted the answer from Property 'assign' does not exist on type 'ObjectConstructor' like this:

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

Sharing for anyone with the same situation

go to "tsconfig.json" and adding :

"lib": ["es2019"];