web-dev-qa-db-fra.com

À l'aide de TypeScript, et Object.assign me donne une erreur "la propriété 'assign' n'existe pas sur le type 'ObjectConstructor'"

Je réécris ma question parce que tout à l’heure, cela n’avait guère de sens et je n’étais pas très clair.

Je reçois des données de l'API qui ressemblent à ceci:

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

Donc, dans mon code, j'ai une variable photos et une méthode appelée getPhotos()

J'utilise le défilement infini et lorsque j'atteins le bas de la page, j'appelle à nouveau 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
    )
}

Donc si la prochaine fois que je l’appelle, je récupère {"photos":[{"id":2,"title":"photo_2_title"}]}, Alors j’essaie de régler this.photos Sur

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

quelqu'un peut-il m'aider avec pourquoi
jsfiddle.net/ca46hLw9 ne fonctionne pas? Je pensais que assign était supposé fusionner le contenu d'un objet, n'est-ce pas?

35
user1354934

Object.assign est une fonctionnalité ECMAScript2015 et n’existe pas dans ECMAScript5 et versions antérieures.

Vous ciblez probablement pour compiler votre TypeScript pour ECMAScript5. Par conséquent, l'interface Object n'a pas défini assign.

Vous pouvez soit cibler ECMAScript2015 en modifiant la configuration de votre compilateur TS avec

target: 'es6'

ou vous pouvez étendre l'interface ObjectConstructor avec la méthode assign

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

(vous pouvez ajouter cette déclaration n'importe où, redéclarer une interface l'étend au lieu de l'écraser)

Ou vous pouvez contraindre Object à any et ignorer son typage:

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

Quel que soit votre choix, gardez à l'esprit que si vous voulez que cela fonctionne sur les anciens navigateurs, vous devez ajouter un remplissage multiple. La plupart des navigateurs modernes sont sur le point de mettre en œuvre le jeu de fonctionnalités ES2015, mais ils n'y sont pas à 100%, ce qui signifie que certaines parties de votre code échoueront quand même si vous utilisez la fonctionnalité ES2015.

TypeScript ne se polyfillera pas Object.assign lorsque vous ciblez ES5 ou une version antérieure, c’est pourquoi vous obtenez cette erreur. D'autre part, Babel a des polyfill sous forme de plugins, ce qui signifie que vous devez incorporer la transpilation de Babel dans votre pipeline de construction, voir: https://babeljs.io/docs/plugins/transform-object -assign /

Enfin, vous pouvez utiliser une bibliothèque telle que Lodash ou jQuery, qui ont leur propre implémentation de Object.assign (appelé extend)

65
vileRaisin

Avec TypeScript 2.1 ou supérieur, vous pouvez utiliser la syntaxe Object spread à la place.

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

L'ordre de spécification des opérations d'étalement détermine les propriétés qui se retrouvent dans l'objet résultant. les propriétés dans les spreads ultérieurs "gagnent" les propriétés précédemment créées.

53
paibamboo

Pour TypeScript version 2.0 ou ultérieure, modifiez simplement le fichier tsconfig.json afin que la section "lib" contienne "es6":

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