使用 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' 上不存在”的主要内容,如果未能解决你的问题,请参考以下文章
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