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

Posted

技术标签:

【中文标题】使用 TypeScript 和 Object.assign 给我一个错误“属性 \'assign\' 在类型 \'ObjectConstructor\' 上不存在”【英文标题】:Using TypeScript, and Object.assign gives me an error "property 'assign' does not exist on type 'ObjectConstructor'"使用 TypeScript 和 Object.assign 给我一个错误“属性 'assign' 在类型 'ObjectConstructor' 上不存在” 【发布时间】:2016-12-16 01:20:29 【问题描述】:

我再次写下我的问题,因为之前它没有什么意义,而且我也不是很清楚。

我从 API 接收数据,如下所示:

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

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

我正在使用无限滚动,所以当我到达页面底部时,我会再次调用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
    )

所以如果下次我调用它时,我会返回"photos":["id":2,"title":"photo_2_title"],然后我会尝试将this.photos 设置为

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

谁能帮我解释一下为什么 jsfiddle.net/ca46hLw9 不起作用?我认为 assign 应该将对象的内容合并在一起,对吗?

【问题讨论】:

【参考方案1】:

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

您很可能打算为 ECMAScript5 编译您的 Typescript,因此 Object 接口没有定义 assign

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

target: 'es6'

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

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

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

或者您可以将Object 强制转换为any 并忽略其输入:

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

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

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

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

【讨论】:

扩展的 objectconstructor 会充当 polyfill 吗? 嗨,我想知道我是否做错了什么。我用简单的对象 a: 1 进行了测试,并尝试做 const test = Object.assign( a: 1, b: 2); 但是当我 console.log(test); 我只看到 b: 2 @user1354934 这是因为您正在尝试进行深度克隆(对象内部的对象)。 Object.assign 显然只做浅克隆。请参阅 MDN 文档中的第二个示例:developer.mozilla.org/en/docs/Web/javascript/Reference/… 有点晚了,但我认为 Angular 2 确实填充了 Object.Assign - 至少如果你使用 Angular CLI。有一个 src/polyfills.ts 文件,其中包含对 core-js/es6/object 的引用,而这又似乎包含 Object.Assign polyfill。【参考方案2】:

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

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

指定展开操作的顺序决定了哪些属性 最终出现在结果对象中;后来传播中的属性“胜出” 覆盖以前创建的属性。

【讨论】:

例如:const opts = ...defaults, ...options obj 是从new 表达式创建的不同。 不幸的是,当“obj”是常量时,这将不起作用。否则这是一个很好的解决方案。【参考方案3】:

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

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

【讨论】:

以上是关于使用 TypeScript 和 Object.assign 给我一个错误“属性 'assign' 在类型 'ObjectConstructor' 上不存在”的主要内容,如果未能解决你的问题,请参考以下文章

从 Object as src 链接到 img 标签

Cannot format given Object as a Date

pickle.PicklingError: Can't pickle: it's not the same object as

超越yolov3,Centernet 原理详解(object as points)

PicklingError: Can't pickle <class 'decimal.Decimal'>: it's not the same object as decimal.Dec

带外键Mysql