I am using TypeScript in my application, where I use function:
Object.assign(this.success, success.json())
However, during compilation, I r
You can use spread operator as in ES6
const obj = {...this.success,...success.json()};
tsconfig.json
file):You should add the lib
property to your tsconfig.json
and then your editor will use the bundled typescript type definitions and also give you intellisense.
Just add the "lib": ["esnext", "dom"]
to your tsconfig.json
and restart VS Code
{
"compilerOptions": {
// ...
"target": "es5",
"lib": ["esnext", "dom"]
// ...
}
}
See all tsconfig.json
options here.
<TypeScriptLib>esnext, dom</TypeScriptLib>
See all MSBuild typescript compiler options and usage here.
If you've configured your project to use the built-in types and restarted your editor, then your resulting type will look like this instead of the type being any
when you use Object.assign
:
Note that if you are transpiling to ES5 or lower and are targeting IE11, you will need to include polyfills because the typescript compiler will not include the polyfills for you.
If you'd like to include the polyfills (which you should) then I would recommend using core-js's polyfills.
npm install --save core-js
or
yarn add core-js
Then in the entry point in your app (e.g. /src/index.ts
) add the import for core-js
at the top of the file:
import 'core-js';
If you're not using a package manager then you can just paste the following polyfill taken from MDN in some place in your code that runs before the your usage of Object.assign
.
if (typeof Object.assign != 'function') {
// Must be writable: true, enumerable: false, configurable: true
Object.defineProperty(Object, "assign", {
value: function assign(target, varArgs) { // .length of function is 2
'use strict';
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
writable: true,
configurable: true
});
}
You can use type assertion, like this:
(<any>Object).assign(this.success, success.json())
This is caused by you using an ECMAScript 6 feature and targeting ECMAScript 5 or 3. Easiest fix is to set the right target, for example if you are using Grunt:
options: {
target: 'es6'
}
of change the relevant property tab in Visual Studio, or manually by editing your .csproj file and finding the TypeScriptTarget element and changing to ES6, for example:
<TypeScriptTarget>ES6</TypeScriptTarget>
If you need to target ES5, then merely add the following to your TypeScript code
declare interface ObjectConstructor {
assign(target: any, ...sources: any[]): any;
}
That merges the extra method in, solving the issue. More details here. You may need a polyfill though, depending on your browser compatibility requirements - for example this one from MDN:
if (typeof Object.assign != 'function') {
(function () {
Object.assign = function (target) {
'use strict';
if (target === undefined || target === null) {
throw new TypeError('Cannot convert undefined or null to object');
}
var output = Object(target);
for (var index = 1; index < arguments.length; index++) {
var source = arguments[index];
if (source !== undefined && source !== null) {
for (var nextKey in source) {
if (source.hasOwnProperty(nextKey)) {
output[nextKey] = source[nextKey];
}
}
}
}
return output;
};
})();
}
I faced this issue when testing a React application with Jest using @testing-library/react
. The fix for me was to add the following to my setupTests.ts
:
declare global {
interface Object {
/**
* Returns an array of values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
values<T>(o: { [s: string]: T } | ArrayLike<T>): T[];
/**
* Returns an array of values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
values(o: {}): any[];
/**
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
entries<T>(o: { [s: string]: T } | ArrayLike<T>): [string, T][];
/**
* Returns an array of key/values of the enumerable properties of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
entries(o: {}): [string, any][];
}
}
Why not use the spread operator?
return {this.success, ...success.json() || {}};