"ObjectConstructor"类型中不存在属性"assign"

uks*_*ksz 121 typescript

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

Object.assign(this.success, success.json())
Run Code Online (Sandbox Code Playgroud)

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

 error TS2339: Property 'assign' does not exist on type 'ObjectConstructor'.
Run Code Online (Sandbox Code Playgroud)

你知道我怎么能摆脱这个错误?

Ric*_*ler 155

配置:

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

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

只需添加"lib": ["es2015", "es2017", "dom"]到您的tsconfig.json并重新启动VS代码

{
    "compilerOptions": {
        // ...
        "target": "es5",
        "lib": ["es2015", "es2017", "dom"]
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

查看此处的所有tsconfig.json选项.

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

<TypeScriptLib>es2015, es2017, dom</TypeScriptLib>
Run Code Online (Sandbox Code Playgroud)

在此处查看所有MSBuild typescript编译器选项和用法.


检查你的工作:

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

代码示例1


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

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

如果你想包括polyfills(你应该),那么我建议使用core-js的polyfill.

npm install --save core-js

如果您正在使用webpack,那么您可以添加特定的polyfill(或所有这些)作为另一个入口点.然后将填充物包含在束中.

import 'core-js';
Run Code Online (Sandbox Code Playgroud)

如果您没有使用/src/index.ts,core-js那么您可以将以下从MDN取出的polyfill粘贴到您使用之前运行的代码中的某个位置npm.

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
  });
}
Run Code Online (Sandbox Code Playgroud)

  • 我试过 "lib":["es2015","es2017","dom"] 但我仍然得到 **Property 'values' 在类型 'ObjectConstructor' 上不存在。**,我猜它不在规范中 (3认同)
  • @AQuirky`TypeScriptTarget`选项更改了EmcaScript的目标版本(〜正式的javascript名称).仅供参考:"ES2015"与IE11不兼容(如果您必须支持它).您仍然可以将`TypeScriptTarget`设置为`ES5`,同时将`TypeScriptLib`设置为`DOM,ES2015`以实现相同的修复,同时还保持与IE11兼容(但如果您不必支持IE,那么只需设置` TypeScriptTarget`to`ES2015`). (2认同)

Rob*_*ean 124

这是由于您使用ECMAScript 6功能并定位ECMAScript 5或3.最简单的修复方法是设置正确的目标,例如,如果您使用的是Grunt:

options: {
    target: 'es6'
}
Run Code Online (Sandbox Code Playgroud)

更改Visual Studio中的相关属性选项卡,或手动编辑.csproj文件并查找TypeScriptTarget元素并更改为ES6,例如:

<TypeScriptTarget>ES6</TypeScriptTarget>
Run Code Online (Sandbox Code Playgroud)

如果需要定位ES5,则只需将以下内容添加到TypeScript代码中即可

declare interface ObjectConstructor {
    assign(target: any, ...sources: any[]): any;
}
Run Code Online (Sandbox Code Playgroud)

这将合并额外的方法,解决问题.更多细节在这里.您可能需要一个polyfill,具体取决于您的浏览器兼容性要求 - 例如来自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;
    };
  })();
}
Run Code Online (Sandbox Code Playgroud)

  • @JoeKeene这个答案并没有像TS 2.0+那样以最好的方式解决问题.如果您的目标是ES5,那么您应该使用`--lib es2015`编译器选项.我上面的方法的问题是,如果你``声明``Object.assign`函数而不是使用内置声明,那么你将无法获得正确的输入和文档.他们添加了`--lib`选项,因此您不必重新声明已经是标准一部分的接口. (5认同)

Ami*_*mid 122

您可以使用类型断言,如下所示:

(<any>Object).assign(this.success, success.json())
Run Code Online (Sandbox Code Playgroud)

  • 哇,看起来超级hacky ..你能解释一下(<any> Object)做什么吗? (29认同)
  • 虽然这似乎是一个解决方案,但它确实不应该被视为一个解决方案.而不是简单地添加歧义并隐藏转换器错误(这样做),实际修复它们并从控制台获得有用的反馈要好得多. (27认同)
  • 这只是投射和隐藏问题.您需要在特定浏览器等中使用polyfill.这将导致在某些浏览器中运行错误 (6认同)
  • 我建议任何在这里浏览的人进一步向下滚动,在其中解释要添加到`tsconfig`中的内容,这是比此方法更好的解决方案。 (3认同)