我在我的应用程序中使用 TypeScript,我使用函数:
Object.assign(this.success, success.json())
但是,在编译期间,我收到以下错误:
error TS2339: Property 'assign' does not exist on type 'ObjectConstructor'.
你知道我怎样才能摆脱这个错误吗?
配置:
如果您使用的是 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
});
}
您可以使用 type assertion,如下所示:
(<any>Object).assign(this.success, success.json())
tsconfig
的内容,这是一个比这个更好的解决方案。
这是由于您使用 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;
};
})();
}
--lib es2015
编译器选项。我对上述方法的问题是,如果您使用 declare
Object.assign
函数而不是使用内置声明,那么您将无法获得正确的输入和文档。他们添加了 --lib
选项,因此您不必重新声明已经是标准一部分的接口。
.d.ts
) 文件,而不是打字稿 (.ts
) 文件。
tsconfig.json
中将 "target": "es5",
更改为 "target": "es6",
。它起作用了(y)
Object.values
,它必须是 "target": "es2017"
,因为这是相同错误代码的最高搜索结果。
您可以像在 ES6 中一样使用扩展运算符
const obj = {...this.success,...success.json()};
我添加了类型:
typings install dt~es6-shim --global --save
为什么不使用扩展运算符?
return {this.success, ...success.json() || {}};
Object.assign
涵盖的某些场景中,因为后者接受任意数量的对象。 return Object.assign({}, ...arrayOfObjects);
。
我在使用 @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][];
}
}
Object.values
is in the spec. 和 typescript has typings for it。"lib": [ "es2015", "es2017", "dom" ]
TypeScriptTarget
选项更改 EmcaScript 的目标版本(~正式的 javascript 名称)。仅供参考:ES2015
与 IE11 不兼容(如果您必须支持它)。您仍然可以将TypeScriptTarget
设置为ES5
,同时将TypeScriptLib
设置为DOM, ES2015
以实现相同的修复,同时还保持与 IE11 的兼容性(但如果您不必支持 IE,则只需设置TypeScriptTarget
到ES2015
)。