如何在Typescript中使用Object.values?


135

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

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'

Answers:


106

改用Object.keys。

const data = {
  a: "first",
  b: "second",
};

const values = Object.keys(data).map(key => data[key]);

const commaJoinedValues = values.join(",");
console.log(commaJoinedValues);

90
请注意,这是一种替代方法(一个不错的选择!),而不是如何Object.values在TS中使用ES7 来解决OP的编译错误的实际答案。为此,您只需要ES2017在您的--lib环境中即可。
亚伦·比尔

4
@Aaron您的解决方案是如此复杂,以至于任何刚接触Typescript的人都无法接受,要进行编译,您必须添加ES2017lib,并且必须在使用它的地方包含polyfills库。针对不同的人提供不同的答案为准。
holi-java

9
@ holi-jave这不是“我的解决方案”,而是TS和非标准JS功能的工作方式,例如OP尝试使用的方式ES7/Object.values()。也许您认为它很复杂(我不同意),但这只是尝试使用像Object.values()今天这样的未来功能的本质。一直都是这种方式。Object.keys()如果您以ES3为目标或想支持IE8,甚至应该仍然进行polyfill(希望您不再使用了!)通常,了解ES功能,浏览器支持以及进行web开发时的polyfill是一个好主意!
亚伦·比尔

@Aaron我并不是说这很复杂,但是对于刚接触打字稿/ JavaScript的人来说,它更复杂,因此不被接受。
holi-java


224

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

解决方案:在es2017编译器选项中使用es2017.object--lib

例如,使用tsconfig.json

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

需要注意的是针对ES2017以打字稿没有发出polyfills在浏览器ES2017(指上述解决您的编译错误,但你仍然可以遇到一个运行时错误,因为该浏览器没有实现ES2017 Object.values),它是由你来填充工具项目如果需要,请自己编写代码。而且,由于Object.values并非所有浏览器都很好地支持(在撰写本文时),因此您绝对希望使用polyfill:core-js可以完成工作


1
@ErikvanVelzen您已编辑答案以将大小写更改为ES2017es2017但AFAIK并不是必须的,但我一直想学习,是否有更改的原因?
亚伦·比尔

2
^要回答我自己的问题:ES2017DOM(大写)在tsc --init注释中列为有效值,并且可以在编译器中正常工作,但是JSON模式仅枚举es2017dom(小写)选项,因此JSON IDE /棉短绒意志的标志ES2017DOM如无效的值(即使它们是有效的)。有点混乱。
亚伦·比尔

确实,这就是原因。如您所述,它确实可以大写。tsc --help显示小写字母
Erik van Velzen

难道不是在core-js中包含了core-js,如果没有的话,如何添加pollyfill?
Samiullah Khan,

1
@ Totty.js TS包含的库文件用于 类型检查,换句话说,它实际上不会为诸如此类的东西发出任何JS库polyfill Object.values()。换句话说,如果您在没有的浏览器中运行,则可以解决编译错误,但仍然会遇到运行时错误Object.values()
亚伦·比尔

18

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


4
@Aaron发布时,有评论表明使用特定版本Angular的人在更新无法使用的lib时遇到问题。这就是为什么我把if for some reason you can't update to ES7 in tsconfig
mtpultz '19

11

代替

Object.values(myObject);

Object["values"](myObject);

在您的示例情况下:

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

这将隐藏ts编译器错误。


1
您是天才(^-')b
harufumi.abe

元素隐式具有“任何”类型,因为类型“ ObjectConstructor”没有索引签名
。ts

6
这是对TS的误用。您应该使用该lib设置来配置编译器,以反映您的使用方式,而不是故意逃避编译器。
亚伦·比尔

1
@AaronBeall如果由于某种原因您不能升级到es2017
Dino,

@Dino您无需升级到es2017,可以使用core-js一直填充到ES5。TypeScript没有运行时,lib设置只是为了进行正确的类型检查。
亚伦·比尔

11

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

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

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

4

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

就我而言,问题出在该部分tsconfig.lib.jsones2017包含的库文件夹中lib

任何使用Angular 6遇到此问题的人都只需要确保更新您tsconfig.lib.json的应用程序即可tsconfig.json


我已经将es2017放在tsconfig.lib和tsconfig.json中,但是在尝试使用条目时,仍然出现错误“对象上不存在条目”错误。还有什么我应该更改/更新的吗?
莫里斯

我刚刚将tsconfig.lib中的目标更改为es2017,仍然是相同的错误。
莫里斯

2

tslint这里配置规则总是Object["values"](myObject)Object.values(myObject)

如果您遇到相同的问题,有两个选择:

(Object as any).values(myObject)

要么

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

1
为什么要使用Object["values"]
亚伦·比尔

-4

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

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);

瞧-没有编译错误;)


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.