ChatGPT解决这个技术问题 Extra ChatGPT

“ObjectConstructor”类型上不存在属性“assign”

我在我的应用程序中使用 TypeScript,我使用函数:

Object.assign(this.success, success.json())

但是,在编译期间,我收到以下错误:

 error TS2339: Property 'assign' does not exist on type 'ObjectConstructor'.

你知道我怎样才能摆脱这个错误吗?

请考虑更改已接受的答案 - 从那时起已经发布了更好的答案和更多的赞成票。

R
Rico Kahler

配置:

如果您使用的是 VS 代码(或者如果您看到 tsconfig.json 文件):

您应该将 lib 属性添加到您的 tsconfig.json,然后您的编辑器将使用捆绑的 typescript 类型定义并为您提供智能感知。

只需将 "lib": ["esnext", "dom"] 添加到您的 tsconfig.json 并重新启动 VS Code

{
    "compilerOptions": {
        // ...
        "target": "es5",
        "lib": ["esnext", "dom"]
        // ...
    }
}

查看所有 tsconfig.json 选项 here

如果您使用的是 Visual Studio 或 MSBuild,请包含此标记:

<TypeScriptLib>esnext, dom</TypeScriptLib>

查看所有 MSBuild typescript 编译器选项和用法 here

检查你的工作:

如果您已将项目配置为使用内置类型并重新启动编辑器,则生成的类型将如下所示,而不是使用 Object.assign 时的 any

https://i.stack.imgur.com/8VM3Y.png

关于 polyfill 和旧版浏览器兼容性的注意事项:

请注意,如果您要转译到 ES5 或更低版本并以 IE11 为目标,则需要包含 polyfill,因为 typescript 编译器不会为您包含 polyfill。

如果你想包含 polyfills(你应该这样做),那么我建议使用 core-js 的 polyfills。

npm install --save core-js

或者

yarn add core-js

然后在应用程序的入口点(例如 /src/index.ts)中,在文件顶部添加 core-js 的导入:

import 'core-js';

如果您没有使用包管理器,那么您只需将以下 polyfill taken from 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
  });
}

我尝试了 "lib":["es2015","es2017","dom"] 但我仍然得到 Property 'values' does not exist on type 'ObjectConstructor'。我猜它不在规范中
@Nikos 您是否重新启动了 vs 代码? Object.values is in the spec.typescript has typings for it
如果万一 WebStorm 出现错误,您需要在此处安装 Javascript.next 插件:plugins.jetbrains.com/plugin/…
修改 tsconfig.json 是唯一适合我的解决方法。即添加"lib": [ "es2015", "es2017", "dom" ]
@AQuirky TypeScriptTarget 选项更改 EmcaScript 的目标版本(~正式的 javascript 名称)。仅供参考:ES2015 与 IE11 不兼容(如果您必须支持它)。您仍然可以将 TypeScriptTarget 设置为 ES5,同时将 TypeScriptLib 设置为 DOM, ES2015 以实现相同的修复,同时还保持与 IE11 的兼容性(但如果您不必支持 IE,则只需设置 TypeScriptTarget ES2015)。
A
Amid

您可以使用 type assertion,如下所示:

(<any>Object).assign(this.success, success.json())

哇,看起来超级hacky..你能解释一下 (Object) 做什么吗?
好的,我看到我声明 Object 的类型为 any。
尽管这似乎是一个解决方案,但它确实不应该被视为一个解决方案。与其简单地添加歧义并隐藏编译器错误(这样做),不如实际修复它们并从控制台获得有用的反馈。
这只是铸造和隐藏问题。您可能需要在特定浏览器等中使用 polyfills。这将导致在某些浏览器中运行错误
我建议任何在这里查看的人进一步向下滚动,其中解释了要添加到您的 tsconfig 的内容,这是一个比这个更好的解决方案。
R
Robert MacLean

这是由于您使用 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;
}

这合并了额外的方法,解决了这个问题。更多详情here。不过,您可能需要一个 polyfill,具体取决于您的 browser compatibility 要求 - 例如来自 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;
    };
  })();
}

@JoeKeene 这个答案并没有像 TS 2.0+ 那样以最好的方式解决问题。如果您的目标是 ES5,那么您应该使用 --lib es2015 编译器选项。我对上述方法的问题是,如果您使用 declare Object.assign 函数而不是使用内置声明,那么您将无法获得正确的输入和文档。他们添加了 --lib 选项,因此您不必重新声明已经是标准一部分的接口。
为此,我必须将接口声明添加到类型 (.d.ts) 文件,而不是打字稿 (.ts) 文件。
@uksz 也许因为这不是 hacky,它应该被接受?
我在 tsconfig.json 中将 "target": "es5", 更改为 "target": "es6",。它起作用了(y)
对于 Object.values,它必须是 "target": "es2017",因为这是相同错误代码的最高搜索结果。
F
Fahd Allebdi

您可以像在 ES6 中一样使用扩展运算符

const obj = {...this.success,...success.json()};


S
Sergejs

我添加了类型:

typings install dt~es6-shim --global --save

看起来像我回复的相同类型?或者我错过了什么?
D
Dave

为什么不使用扩展运算符?

return {this.success, ...success.json() || {}};


绝对优选使用传播,但不能在 Object.assign 涵盖的某些场景中,因为后者接受任意数量的对象。 return Object.assign({}, ...arrayOfObjects);
L
Liran H

我在使用 @testing-library/react 使用 Jest 测试 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][];
    }
}