Javascript 使用 TypeScript 和 Object.assign 给我一个错误“类型‘ObjectConstructor’上不存在属性‘assign’”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38860161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 21:56:51  来源:igfitidea点击:

Using TypeScript, and Object.assign gives me an error "property 'assign' does not exist on type 'ObjectConstructor'"

javascripttypescript

提问by user1354934

I am writing my question again because earlier it made little sense and I wasn't very clear.

我再次写我的问题,因为早些时候它没有意义而且我不是很清楚。

I am receiving data from API that looks something like this:

我从 API 接收数据,看起来像这样:

{"photos":[{"id":1,"title":"photo_1_title"}]}

So, in my code, I have a photosvariable, and a method called getPhotos()

所以,在我的代码中,我有一个photos变量和一个名为getPhotos()

I am using infinite scroll so when I reach the bottom of the page, I call getPhotos()again.

我正在使用无限滚动,所以当我到达页面底部时,我getPhotos()再次调用。

photos: any;

getPhotos() {
  this.photoService.getPhotos()
    .subscribe(
      photos => this.photos = photos
      // here, instead of doing this, I want to add the array of photos I get back to this.photos using Object.assign however it is giving me the said error
    )
}

So if the next time I call it, I get back {"photos":[{"id":2,"title":"photo_2_title"}]}, then I am trying to set this.photosto be

所以如果下次我打电话给它,我回来了{"photos":[{"id":2,"title":"photo_2_title"}]},那么我试图设置this.photos

{"photos":[{"id":1,"title":"photo_1_title"}, {"id":2,"title":"photo_2_title"}]}

can someone help me with why
jsfiddle.net/ca46hLw9 doesn't work? I thought assign is supposed to merge contents of an object together right?

有人可以帮我解释为什么
jsfiddle.net/ca46hLw9 不起作用吗?我认为分配应该将对象的内容合并在一起,对吗?

回答by vileRaisin

Object.assignis an ECMAScript2015 feature and does not exist in ECMAScript5 and lower.

Object.assign是 ECMAScript2015 的特性,在 ECMAScript5 及更低版本中不存在。

You're most likely targeting to compile your Typescript for ECMAScript5 and therefor the Object interface does not have assigndefined.

你最有可能的目标是为 ECMAScript5 编译你的 Typescript,因此 Object 接口没有assign定义。

You can either target ECMAScript2015 by changing your TS compiler configuration with

您可以通过更改您的 TS 编译器配置来定位 ECMAScript2015

target: 'es6'

target: 'es6'

or you can extend the ObjectConstructor interface with the method assign

或者您可以使用该方法扩展 ObjectConstructor 接口 assign

declare interface ObjectConstructor {
    assign(...objects: Object[]): Object;
}

(you can add this declaration anywhere, redeclaring an interface extends it instead of overwriting it)

(你可以在任何地方添加这个声明,重新声明一个接口来扩展它而不是覆盖它)

Or you can coerce Objectto anyand ignore its typing:

或者你可以强迫Objectany,而忽略它的打字:

(<any>Object).assign( this.photos, photos )

(<any>Object).assign( this.photos, photos )

Whichever you choose, keep in mind that if you want this to run on older browsers you need to add a polyfill. Most modern browsers are fairly close to implementing the ES2015 feature set, but they're not 100% there, meaning that some parts of your code will still fail if you rely on ES2015 functionality.

无论您选择哪种方式,请记住,如果您希望它在旧浏览器上运行,您需要添加一个 polyfill。大多数现代浏览器都非常接近于实现 ES2015 功能集,但它们并不是 100% 实现的,这意味着如果您依赖 ES2015 功能,您的代码的某些部分仍然会失败。

Typescript will not polyfill Object.assignwhen targetting ES5 or older, that is why you are getting this error. On the other hand, Babel does have polyfills in the form of plugins, which would mean you need to incorporate Babel transpilation into your build pipeline, see: https://babeljs.io/docs/plugins/transform-object-assign/

Object.assignES5 或更早版本为目标时,Typescript 不会填充,这就是您收到此错误的原因。另一方面,Babel 确实有插件形式的 polyfill,这意味着您需要将 Babel 转译合并到您的构建管道中,请参阅:https://babeljs.io/docs/plugins/transform-object-assign/

As a final option you can consider using a library as Lodash or jQuery, which have their own implementation of Object.assign(called extend)

作为最后的选择,您可以考虑使用库作为 Lodash 或 jQuery,它们有自己的Object.assign(称为extend

回答by paibamboo

With Typescript 2.1or higher, you can use Object spread syntax instead.

使用Typescript 2.1或更高版本,您可以改用对象展开语法。

let obj = { x: 1, y: "string" };
var newObj = {...obj, z: 3, y: 4}; // { x: number, y: number, z: number }

The order of specifying spread operations determines what properties end up in the resulting object; properties in later spreads “win out” over previously created properties.

指定展开操作的顺序决定了结果对象中的最终属性;稍后创建的属性“胜出”先前创建的属性。

回答by Alberto S.

For typescript version 2.0 or higher, just modify the tsconfig.json file so the "lib" section includes "es6":

对于 typescript 2.0 或更高版本,只需修改 tsconfig.json 文件,以便“lib”部分包含“es6”:

"lib": [
  "es5",
  "es6",
  "dom",
  "es2015.collection"
]