【问题标题】: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 应该将对象的内容合并在一起,对吗?

【问题讨论】:

    标签: javascript typescript


    【解决方案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"
    ]
    

    【讨论】:

      猜你喜欢
      • 2016-06-27
      • 2020-10-02
      • 2019-02-17
      • 1970-01-01
      • 2018-01-07
      • 2018-10-13
      • 1970-01-01
      • 2023-02-21
      • 2019-04-12
      相关资源
      最近更新 更多