Свойство assign не существует для типа ObjectConstructor
Я использую TypeScript в своем приложении, где я использую функцию:
Object.assign(this.success, success.json())
Однако во время компиляции я получаю следующую ошибку:
error TS2339: Property 'assign' does not exist on type 'ObjectConstructor'.
У вас есть идеи, как я могу избавиться от этой ошибки?
9 ответов
Вы можете использовать утверждение типа, например так:
(<any>Object).assign(this.success, success.json())
Настройка:
Если вы используете код VS (или если вы видите tsconfig.json
файл):
Вы должны добавить lib
собственность на ваш tsconfig.json
и тогда ваш редактор будет использовать определения типов в связке с машинописью, а также даст вам смысл.
Просто добавьте "lib": ["es2015", "es2017", "dom"]
на ваш tsconfig.json
и перезапустите VS Code
{
"compilerOptions": {
// ...
"target": "es5",
"lib": ["es2015", "es2017", "dom"]
// ...
}
}
Увидеть все tsconfig.json
варианты здесь.
Если вы используете Visual Studio или MSBuild, включите этот тег:
<TypeScriptLib>es2015, es2017, dom</TypeScriptLib>
Посмотрите все опции и использование компилятора машинописи MSBuild здесь.
Проверьте свою работу:
Если вы настроили ваш проект на использование встроенных типов и перезапустили ваш редактор, тогда ваш результирующий тип будет выглядеть так, а не как тип any
когда вы используете Object.assign
:
Примечание о полифиллах и совместимости с более старыми браузерами:
Обратите внимание, что если вы переходите на ES5 или ниже и ориентируетесь на IE11, вам нужно будет включить полифилы, потому что компилятор машинописного текста не будет включать полифилы для вас.
Если вы хотите включить полифилы (что следует), я бы порекомендовал использовать полифилы core-js.
npm install --save core-js
Если вы используете веб-пакет, то вы можете добавить конкретный полифилл (или все они) в качестве другой точки входа. Полифиллы будут включены в комплект.
module.exports = {
// ...
entry: [
'core-js', // or just `'core-js/fn/object/assign',`
'./src/main.ts'
],
// ...
};
Если вы не используете npm
или же webpack
затем вы можете просто вставить следующий полифилл, взятый из MDN, в какое-то место вашего кода, который запускается до использования вами 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
});
}
Это вызвано тем, что вы используете функцию ECMAScript 6 и ориентируетесь на ECMAScript 5 или 3. Самый простой способ - установить правильную цель, например, если вы используете Grunt:
options: {
target: 'es6'
}
изменить соответствующую вкладку свойств в Visual Studio или вручную, отредактировав файл.csproj и найдя элемент TypeScriptTarget и изменив на ES6, например:
<TypeScriptTarget>ES6</TypeScriptTarget>
Если вам нужно ориентироваться на ES5, просто добавьте следующее в ваш код TypeScript
declare interface ObjectConstructor {
assign(target: any, ...sources: any[]): any;
}
Это объединяет дополнительный метод решения проблемы. Подробнее здесь. Возможно, вам понадобится полифилл, в зависимости от требований совместимости вашего браузера - например, этот от 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;
};
})();
}
Почему бы не использовать оператор распространения?
return {this.success, ...success.json() || {}};
Вы можете использовать оператор распространения, как в ES6
const obj = {...this.success,...success.json()};
Я добавил печатать:
typings install dt~es6-shim --global --save
Я столкнулся с той же проблемой! Изменение параметров компилятора в моем коде не сработало. Затем я просто попробовал использовать скобочные обозначения, например:
Object['assign'](this.success, success.json())
Я столкнулся с этой проблемой при тестировании приложения React с помощью Jest, используя
@testing-library/react
. Для меня исправление заключалось в том, чтобы добавить в мои
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][];
}
}
Я знаю, что это было давно, но вот простое решение
(Object as any).assign(this.success, success.json())