【问题标题】:How to use Object.values with typescript?如何将 Object.values 与打字稿一起使用?
【发布时间】:2017-08-15 10:27:34
【问题描述】:

我正在尝试从一个对象中形成一个逗号分隔的字符串,

const data = {"Ticket-1.pdf":"8e6e8255-a6e9-4626-9606-4cd255055f71.pdf","Ticket-2.pdf":"106c3613-d976-4331-ab0c-d581576e7ca1.pdf"};
const values = Object.values(data).map(x => x.substr(0, x.length - 4));
const commaJoinedValues = values.join(',');
console.log(commaJoinedValues);

如何用 TypeScript 做到这一点?

获取错误文件:

severity: 'Error'
message: 'Property 'values' does not exist on type 'ObjectConstructor'.'
at: '216,27'
source: 'ts'

【问题讨论】:

    标签: typescript object


    【解决方案1】:

    Object.values()part of ES2017,你得到的编译错误是因为你需要配置 TS 才能使用 ES2017 库。您可能在当前的 TS 配置中使用 ES6 或 ES5 库。

    解决方案:在您的--lib compiler option 中使用es2017es2017.object

    例如,使用tsconfig.json:

    "compilerOptions": {
        "lib": ["es2017", "dom"]
    }
    

    请注意,使用 TypeScript 定位 ES2017 在浏览器中为 ES2017 发出 polyfill(这意味着上述解决了您的 compile 错误,但您仍然会遇到 runtime 错误,因为浏览器没有实现 ES2017 Object.values),如果需要,您可以自行填充项目代码。因为Object.values is not yet well supported by all browsers(在撰写本文时)你肯定想要一个polyfill:core-jsdo the job

    【讨论】:

    • @ErikvanVelzen 您编辑了答案以将ES2017 的大小写更改为es2017 但AFAIK 这不是必需的,但我一直想学习,是否有改变的理由?跨度>
    • ^ 回答我自己的问题:ES2017DOM(大写)在tsc --init 注释中列为有效值,它在编译器中正常工作,但JSON schema仅枚举 es2017dom(小写)选项,因此 JSON IDE/linter 会将 ES2017DOM 标记为无效值(即使它们有效)。有点混乱。
    • 确实是这个原因。正如您所注意到的,它确实可以大写。 tsc --help 虽然显示小写
    • 是不是core-js包含在angular中,如果没有怎么添加这个pollyfill?
    • @Totty.js TS 包含的库文件仅用于类型检查,换句话说,它实际上不会为 @987654346 之类的东西发出任何 JS 库 polyfill @。换句话说,如果您在没有Object.values() 的浏览器中运行,您可以绕过编译错误,但仍然会遇到运行时错误。
    【解决方案2】:

    改为使用 Object.keys。

    const data = {
      a: "first",
      b: "second",
    };
    
    const values = Object.keys(data).map(key => data[key]);
    
    const commaJoinedValues = values.join(",");
    console.log(commaJoinedValues);
    

    【讨论】:

    • 请注意,这是一个替代方案(一个很好的方案!),而不是关于如何在 TS 中使用 ES7 的 Object.values 来解决 OP 编译错误的实际答案。为此,您只需在 --lib 设置中添加 ES2017
    • @Aaron 您的解决方案是如此复杂,以至于任何新接触 typescript 的人都无法接受,要编译您必须添加 ES2017 lib,并且必须包含使用它的 polyfills 库。针对不同的人给出不同的答案为王。
    • @holi-jave 这不是“我的解决方案”,它只是 TS 和非标准 JS 功能的工作方式,就像 OP 尝试使用 ES7/Object.values() 一样。也许您认为它很复杂(我不反对),但这只是今天尝试使用 Object.values() 等未来功能的本质。一直都是这样。如果你的目标是 ES3 或想要支持 IE8,即使 Object.keys() 仍然应该被 polyfill(希望你不再支持了!)如果你从事 web 开发,了解 ES 特性、浏览器支持和 polyfill 是一个好主意!
    • @Aaron 我并不是说它很复杂,但是对于 typescript/javascript 的新手来说更复杂并且不被接受。
    【解决方案3】:

    如果由于某种原因您无法在 tsconfig 中更新到 ES7,您可以在 TypeScript 中使用 Object.values (<any>Object).values(data)

    【讨论】:

    • @Aaron 在发帖时有 cmets 表示使用特定版本的 Angular 的人在更新它不起作用的库时遇到问题。这就是为什么我把if for some reason you can't update to ES7 in tsconfig
    【解决方案4】:

    代替

    Object.values(myObject);
    

    使用

    Object["values"](myObject);
    

    在你的例子中:

    const values = Object["values"](data).map(x => x.substr(0, x.length - 4));
    

    这将隐藏 ts 编译器错误。

    【讨论】:

    • 你是天才(^-' )b
    • 这是对 TS 的误用。您应该使用 lib 设置配置编译器以反映您如何使用它,而不是故意逃避编译器。
    • @AaronBeall 如果由于某种原因您无法升级到 es2017,这是一个很好的用途
    • @Dino 你不需要升级到 es2017,你可以使用 core-js 来 polyfill 到 ES5。 TypeScript 没有运行时,lib 设置只是为了获得正确的类型检查。
    • @Dino 如果你不能升级到 es2017 为什么要使用 es2017 中定义的函数?
    【解决方案5】:

    我在tsconfig.json 中增加了目标以在 TypeScript 中启用此功能

    {
        "compilerOptions": {
            "target": "es2017",
            ......
        }
    }
    

    【讨论】:

    • 如果您想保持与旧浏览器的兼容性,更改目标不是解决方案。 Typescript 必须能够将 ES2017 语法转换为 ES2015。
    【解决方案6】:

    我刚刚使用 CLI 和工作区使用 ng g library foo 创建了一个库,使用 Angular 6 遇到了这个确切的问题。

    在我的情况下,问题出在库文件夹中的 tsconfig.lib.json 中,而 es2017 未包含在 lib 部分中。

    任何在 Angular 6 中遇到此问题的人,您只需确保更新您的 tsconfig.lib.json 以及您的应用程序 tsconfig.json

    【讨论】:

    • 我已将 es2017 放入 tsconfig.lib 和 tsconfig.json 中,但在尝试使用条目时仍然出现错误“对象上不存在条目”错误。还有什么我应该更改/更新的吗?
    • 刚才我把tsconfig.lib中的target改成了es2017,还是一样的错误。
    【解决方案7】:

    在这里有我的tslint 规则配置总是用Object.values(myObject) 替换行Object["values"](myObject)

    如果您有同样的问题,有两种选择:

    (Object as any).values(myObject)

    /*tslint:disable:no-string-literal*/
    `Object["values"](myObject)`
    

    【讨论】:

    • 你为什么要使用Object["values"]
    【解决方案8】:

    最简单的方法是将Object 转换为any,如下所示:

    const data = {"Ticket-1.pdf":"8e6e8255-a6e9-4626-9606-4cd255055f71.pdf","Ticket-2.pdf":"106c3613-d976-4331-ab0c-d581576e7ca1.pdf"};
    const obj = <any>Object;
    const values = obj.values(data).map(x => x.substr(0, x.length - 4));
    const commaJoinedValues = values.join(',');
    console.log(commaJoinedValues);
    

    瞧——没有编译错误;)

    【讨论】:

      【解决方案9】:

      更简单,使用来自 underscore.js 的 _.values https://underscorejs.org/#values

      【讨论】:

        猜你喜欢
        • 2017-12-25
        • 2021-02-13
        • 2019-04-18
        • 2021-08-21
        • 1970-01-01
        • 2022-11-06
        • 2021-08-14
        • 1970-01-01
        • 2021-09-28
        相关资源
        最近更新 更多