Свойство 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:

Пример кода 1


Примечание о полифиллах и совместимости с более старыми браузерами:

Обратите внимание, что если вы переходите на 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())
Другие вопросы по тегам