Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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:

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

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

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

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.photos to be

{"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?

like image 623
user1354934 Avatar asked Aug 09 '16 20:08

user1354934


People also ask

How do you fix the property does not exist on type {} error in TypeScript?

The "Property does not exist on type '{}'" error occurs when we try to access or set a property that is not contained in the object's type. To solve the error, type the object properties explicitly or use a type with variable key names. Copied!

How do you assign an object in TypeScript?

To use the Object. assign() method in TypeScript, pass a target object as the first parameter to the method and one or more source objects, e.g. const result = Object. assign({}, obj1, obj2) . The method will copy the properties from the source objects to the target object.

What is object assign in Javascript?

Object.assign() The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.


Video Answer


2 Answers

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

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

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

target: 'es6'

or you can extend the ObjectConstructor interface with the method 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 Object to any and ignore its typing:

(<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.

Typescript will not polyfill Object.assign when 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/

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

like image 174
vileRaisin Avatar answered Sep 29 '22 11:09

vileRaisin


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

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.

like image 31
paibamboo Avatar answered Sep 29 '22 13:09

paibamboo