【问题标题】:Property 'entries' does not exist on type 'ObjectConstructor'“ObjectConstructor”类型上不存在属性“条目”
【发布时间】:2018-01-07 10:05:30
【问题描述】:

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

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

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

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

根据快速谷歌,似乎解决方案可能是将 compilerOptions 目标属性从 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,然后重新构建项目并执行“typescriptUsingTsConfig”,但我仍然遇到相同的错误。知道我可以在这里做什么来利用 Object.entries() 函数吗?

【问题讨论】:

    标签: javascript angular typescript ecmascript-6 ecmascript-2017


    【解决方案1】:

    您非常正确,更改target 是错误的方法,更改lib 是正确的方法,但是您指定了错误的语言版本。 According to MDNObject.entries正式加入ES2017规范。

    "lib": ["es2017"]
    

    因此是您必须指定的内容*。

    如果您希望添加 在 ES2017 中添加Object 函数的方法的声明,TypeScript 允许您指定 a more granular value

    "lib": ["es2017.object"]
    

    正如 Alexander Bird 所述,默认情况下,"lib" 选项的隐含值取决于为 "target" 指定的值(如果存在)。

    例如:

    "target": "es2017"
    

    除非明确指定"lib",否则默认情况下会包含相应前缀的"lib.*"

    请注意,您可能希望添加实现本身的 polyfill,such as the this one,以确保它在较旧的运行时中有效。

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

    "lib": ["es2020"]
    

    或者自然而然

    "lib": ["esnext"] 
    

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

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

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

    有关更多详细信息,请参阅TypeScript Handbook

    注意: 一些评论者问为什么更改 --target 而不是 --lib 是错误的,因为两者都会启用代码类型检查?原因是--target 改变了代码的转译方式。例如,"target": "es2017" 表示 async 函数不会针对较旧的运行时进行转换。这是不正确的,因为其目的是启用其他库,而不是更改输出语法,因此区分语法特征和库特征很重要。

    【讨论】:

    • @user8334943 不,你肯定需要 IE 10 的 polyfill。MDN 链接底部有浏览器支持信息。
    • 请注意:如果您尚未使用lib 编译器选项,则可能存在一个基于您的目标的默认值,当您设置lib 时该默认值将被覆盖。有关默认值列表,请参阅 the compiler options documentation。我必须为我的目标显式添加默认的lib 参数以及es2017.object
    • @AluanHaddad 肯定 :) 我同意尽可能长时间地保持更新,我将很快执行更新。这是一个大型应用程序,有许多开发人员,因此需要计划更新。感谢您的意见!
    • 为什么更新lib而不是target更正确?
    • @rjh Target 更改了代码的转译方式。例如,"target": "es2017" 表示 async 函数不会针对较旧的运行时进行转换。这是不正确的,因为其目的是启用其他库,而不是更改输出语法。
    【解决方案2】:

    接受的答案对我不起作用,但我从Property 'assign' does not exist on type 'ObjectConstructor' 调整了答案,如下所示:

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

    分享给有相同情况的人

    【讨论】:

    • 谢谢 Nguyen ......我正在使用带有 typescript 2.6.2 的 Angular 6,这对我有用。如果有人能解释一下,我会很高兴的。
    • 在打字稿操场上为我工作。这是一些严重的巫术
    • 在打字稿操场上,你目前不能设置--lib,所以你必须使用--target来隐式指定--lib
    • 你是个英雄。我无法更改 lib,因为它是由另一个我无法更改 tsconfig 的应用程序生成的。
    猜你喜欢
    • 2018-10-13
    • 1970-01-01
    • 2019-02-17
    • 2016-06-27
    • 2020-10-02
    • 1970-01-01
    • 2018-11-13
    • 2016-12-16
    • 2021-01-09
    相关资源
    最近更新 更多