在1.6或2.0中?
不确定你在找什么。 如果您指的是类型,则它已在lib.es6.d.ts中定义为
/**
* Copy the values of all of the enumerable own properties from one or more source objects to a
* target object. Returns the target object.
* <strong i="6">@param</strong> target The target object to copy to.
* <strong i="7">@param</strong> sources One or more source objects to copy properties from.
*/
assign(target: any, ...sources: any[]): any;
我的意思是实现,TypeScript不包含pollyfills,您可以始终包含您的内容,例如Mozilla为此提供了
如果您要询问mixin模式的类型,这是我们在2.0路线图中一直存在的问题。
谢谢。 我的意思是在TypeScript中编写Object.assign(...)
并转换为es3 / es5 / es6。 因此它在2.0的路线图上。
:+1:
@unional我可能误会了一些东西。 但我认为您的结论不正确。
ES6无论如何都支持Object.assign
,因此,如果您的目标是ES6,则应该能够以TypeScript编写它。
但是,如果您转换到es5及以下版本,则仍然需要一个polyfill,因为es5没有Object.assign
。
作为快速解决方法,请考虑以下polyfill并输入:
interface ObjectConstructor {
assign(target: any, ...sources: any[]): any;
}
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;
};
})();
}
感谢您解决此问题。 很久以前了。 :)是的,我现在知道它只需要为es5使用polyfill。
再次感谢!
当目标设置为es5时,我们会编译此polyfill吗? 我的意思是,由于将编译目标设置为es5,因此这应该能够在es5环境下工作。
当目标设置为es5时,我们将编译此polyfill吗
是的,作为ponyfill:rose::horse:
对不起,我不明白。 ES6支持Object.assign
因此Babel将其转换为ES5目标的polyfill。 我很困惑为什么TypeScript不能像其他ES6功能那样做同样的事情。
@ devoto13谢谢, core-js
运作良好。
我只是有一个愚蠢的问题。 在npm install
和typings install
core-js
我开始为多填充方法获取IntelliSense。 但是我仍然需要在使用它们的每个模块中实际导入这些方法,否则编译后的代码将不包含polyfills,对吗?
@prashaantt任何东西都需要core-js/shim
, Object.assign
将从那时起在全球范围内可用。 我建议将import 'core-js/shim';
放在主模块/入口点的顶部。
谢谢@jesseschalken。 作为后续措施,不是整个shim
导入都会使我的捆绑包膨胀吗? 还是tsc
或ts-loader
足够聪明,只挑选我的代码中实际使用的东西?
@prashaantt这取决于您要定位的浏览器。 您已经知道您定位的浏览器不支持Object.assign
,谁知道还不支持? 如果需要最大范围的浏览器支持,则需要捆绑包中的整个垫片。
如果只需要Object.assign
的polyfill,则可以import 'core-js/modules/es6.object.assign';
,并在需要时添加更多东西(请参阅core-js中的shim.js
以获得列表)文档)。 Webpack将遵循需求图,仅包含必要的模块。
如果您已经在使用Babel,建议您使用import 'babel-polyfill';
而不是直接使用core-js。 它包括core-js/shim
,还包括Generators / async-await的regenerator-runtime
。
对不起,我不明白。 ES6支持Object.assign,因此Babel会将其转换为ES5目标的polyfill。 我很困惑为什么TypeScript不能像其他ES6功能那样做同样的事情。
@prashaantt,当您说Babel _transpiles_ Object.assign
什么意思? 它只是一个功能。 您可以添加polyfill,ponyfill或自己编写,也可以在任何环境中使用它-ES 3、1、5.1、6等。
@aluanhaddad我对babel的理解是,如果您将es5指定为目标并使用Object.assign
,它将自动包含Object.assign
polyfill,如果您不使用它,则不会。 如果打字稿做同样的事情会很好,因为它声称它是“ es2015的超集”,如果它不提供可转换为较旧目标的功能,那不是真的。 (我可能是错的)
@ devoto13,如果您的目标是es5,则至少应发出警告,指出es5不支持Object.assign。 使其完全有效并且不告诉程序员您需要一些随机的polyfill是零意义。
@kyleholzinger您所描述的(针对ES5意味着Object.assign不可用)已经是该行为。
@kyleholzinger它确实会引发错误。 如果使用以下两个文件创建文件夹:
// test.ts
let t = Object.assign({}, {});
// tsconfig.json
{ "target": "es5" }
然后在其上运行tsc
。 您将收到以下错误:
$ tsc
test.ts(1,16): error TS2339: Property 'assign' does not exist on type 'ObjectConstructor'.
在您的项目中,您可能包括一些polyfill的类型输入,但不包括polyfill实现,这就是它失败的原因。
我了解这是目前的行为哈哈。 我的观点是,如果您将目标指定为es5,则打字稿会给您一个有意义的错误,而不是“它不在构造函数上”,那将是一个很好的选择。
@kyleholzinger FWIW,TypeScript 2.1现在支持ES6(ES7?)对象的剩余/扩展,因此我个人发现了较少的理由来烦扰Object.assign
了。 使用本机生成器意味着我在大多数项目中不需要任何polyfill。
确实如此。 不遗漏语言功能真是太好了。 如果Object.assign不依赖于浏览器,并且如果您未使用polyfill,打字稿会警告您,那就太好了。
如果您的tsconfig设置正确,TypeScript会警告您有关assign
无法用于<ES6的情况,方法是首先不给您选择在Object
上自动完成该函数名称的选项。 如果您坚持不懈地手工编写,则会看到红色的花样。 如果您忽略该错误, tsc
将给您以上错误。 但是,如果您也故意忽略了这一点,那么您理应受到的厄运。 ;)
是的,我唯一要说的是es2015规范,因此应该在打字稿中;)
定位es5
如何在节点上使用Object.assign
es5
? 也就是说,代码将在服务器上而不是浏览器中运行。 我也使用填充胶吗?如何使用?
@johnbendi
它取决于节点的版本,也就是说,它取决于所有可填充功能的运行时。
这是测试运行时是否支持Object.assign
$ Node
> Object.assign({ to: 'world' }, { message: 'Hello there!' })
{ to: 'world', message: 'Hello there!' }
如果上述方法奏效,您只需在tsconfig.json的"compilerOptions"."lib"
属性中包含"es2017.object"
。
如果上述方法失败,则添加一个用TypeScript编写的polyfill。
// polyfill-object-assign.ts
if (typeof Object.assign !== 'function') {
Object.assign = function (target, ...args) {
if (!target) {
throw TypeError('Cannot convert undefined or null to object');
}
for (const source of args) {
if (source) {
Object.keys(source).forEach(key => target[key] = source[key]);
}
}
return target;
};
}
并导入
import './polyfill-object-assign';
并且还对运行时支持的情况对tsconfig.json进行了相同的更改。
希望对您有所帮助
@aluanhaddad非常感谢您的见解。 根据您要求我运行的实验,我的节点确实支持Object.assign
。 但是即使添加了"compilerOptions": { "lib": ["es2017.object"] }
我仍然得到squiggles
。 我应该忽略它还是有什么办法可以使它消失。
@aluanhaddad没关系。 现在效果很好。
@aluanhaddad我以前在获取squiggles
时有"compilerOptions": { "lib": ["es2017.object", "es6"] }
squiggles
。 删除es6
似乎可以解决,但是再次重新运行gulp脚本会突然产生一组新的错误。
我的tsconfig.json:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"lib": ["es2017.object"],
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true,
"inlineSources": true,
//"noImplicitAny": true,
"declaration": true,
"noFallthroughCasesInSwitch": true,
// "noImplicitReturns": true,
"removeComments": true,
"stripInternal": true,
"outDir": "dist"
},
"files": ["src/main.ts"],
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules"
]
}
我的新错误示例:
error TS2318: Cannot find global type 'Array'.
error TS2318: Cannot find global type 'Boolean'.
error TS2318: Cannot find global type 'Function'.
error TS2318: Cannot find global type 'IArguments'.
error TS2318: Cannot find global type 'Number'.
error TS2318: Cannot find global type 'RegExp'.
error TS2318: Cannot find global type 'String'.
error TS2339: Property 'bind' does not exist on type '(message?: any, ...optionalParams: {}) => void'.
error TS2339: Property 'bind' does not exist on type '(message?: any, ...optionalParams: {}) => void'.
error TS2322: Type '{}' is not assignable to type
error TS2304: Cannot find name 'Promise'.
因此,有没有一种方法可以使用您的推荐并仍然使打字稿正确编译?
@johnbendi是的,当然可以。
用途我只是在建议添加特定条目"es2017.object"
因为您的请求具有特殊性。
我相信"lib": ["es6"]
不再正确,应该是"lib": ["es2015"]
。
尝试"lib": ["es2015", es2017.object"]
或仅"lib": ["es2017"]
。
我认为所缺少的是一种干净的方式来表达“我有一个es6 polyfill,而不是您的商务打字稿,只是假设我这样做” :)。
因为设置target: "es6"
做到这一点,但是大概也可以使用非polyfillable es6功能生成代码。
显式地要求core-js实质上迫使您具有填充,因为TS会抱怨,所以您不能进行有垫片和无垫片构建。
在tsconfig.json
files
中将node_modules/typescript/lib/lib.es6.d.ts
到files
做到这一点,但是..看起来并不干净...(或者我错过了实现这一目标的明显方法吗?)
@himdel只需使用
{
"compilerOptions": {
"lib": [
"es2015"
]
}
}
它运行完美-我已经做了几个月了。
或您希望的任何子集:
{
"compilerOptions": {
"lib": [
"es2015.core",
"es2016.array.include"
]
}
}
我仍然不知道该怎么做。 当我有target: "es5"
tsc时,总是会将Object.assign
转换成对polyfill的调用。 添加库对我完全没有任何改变。
在我的情况下,我希望将箭头功能转换为普通功能,但不修改Object.assign
和Array.includes
类的静态调用。
tsc应该有一个标志来告诉它仅可转译语法功能,不能告诉它诸如静态方法Object
, Array
等的polyfill功能。
当我有目标时:“ es5” tsc将始终将Object.assign转换为对polyfill的调用。
@danez TypeScript不会修改对Object.assign
的调用。 听起来您可能正在通过Babel运行代码?
@RyanCavanaugh确实如此。 Babel不参与该过程。
它所做的基本上是在改变这一点:
var a = Object.assign({}, {});
进入这个
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
var a = _assign({}, {});
@danez您可以发布实际的复制品吗? 编译器未发出该代码
我没有存储库,但这是tsconfig:
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"module": "ES2015",
"target": "es5",
"outDir": "js/lib/es"
},
"include": [
"js/**/*.ts",
],
"exclude": [
"**/__tests__/**/*.ts"
]
}
然后我简单地叫tsc
@danez恐怕您必须发布实际的抄录。
C:\Throwaway\oat>type a.ts
var a = Object.assign({}, {});
C:\Throwaway\oat>type tsconfig.json
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"module": "ES2015",
"target": "es5",
"outDir": "js/lib/es"
},
"include": [
"*.ts",
]
}
C:\Throwaway\oat>tsc
a.ts(1,16): error TS2339: Property 'assign' does not exist on type 'ObjectConstructor'.
C:\Throwaway\oat>type js\lib\es\a.js
var a = Object.assign({}, {});
可能相关: https :
@unional可以正常工作。 编译器具有用于提供语法支持的帮助程序,但它不能在全局变量上_ever_重写功能。 @danez不能通过TypeScript代码访问该帮助程序。
const foo = { foo: 'bar' };
const bar = { ...foo };
将发出:
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
var foo = { foo: 'bar' };
var bar = __assign({}, foo);
我认为您无法提供一个示例,其中Object.assign()
被重写为__assign
,它仅用于对象扩展语法支持。
@kitsonk是的,我正在使用对象传播,您是对的。 因此,如果将对象传播简单地转换为Object.assign
@danez是在您定位支持Object.assign()
(例如,目标为es2015 +)时。
例如,这:
const foo = { foo: 'bar' };
const bar = { ...foo };
将输出:
const foo = { foo: 'bar' };
const bar = Object.assign({}, foo);
@kitsonk是的,我知道,但是我的目标是es5 _syntax_,所有ES2017 +全局变量都由core-js填充。 所以我指的是一种可以输出es5语法但假定所有内置函数都可用的模式。 类似于babel使用useBuiltins
选项进行的操作: https :
通常,我们不会竭尽全力为“混合”运行时目标提供特殊支持,但还有其他可用选项。
您可以将__assign
注入到全局范围(以及其他任何帮助器,例如__extends
)并与--noEmitHelpers
。
是的,我知道,但是我的目标是es5 _syntax_
我觉得这是不填充诸如Object.assign
类的功能的主要问题。 一定要采取另一种立场-使用价差不能用__assign
代替它的用法,但是当您直接调用它时却不能,这令人困惑
您不能在使用价差时用__assign代替它的用法,但在直接调用时不能用__assign代替,这令人困惑
我可以理解,您会感到困惑,但是如果您坚持这句话,TypeScript会提供_syntatical rewrites_而非_functional polyfills_。 TypeScript在行为方式上是完全一致的,并且对它的作用持肯定态度,并且99%的时间对最终用户没有影响。
正如@RyanCavanaugh所说,可以利用一组polyfills,再加上tslib
,再加上--noEmitHelpers
加上一个表示以下内容的全局脚本:
__assign = Object.assign;
但这确实是“优胜劣汰”的TypeScript,并且可以说它将提供任何在现实世界中可衡量的性能改进。
最有用的评论
对不起,我不明白。 ES6支持
Object.assign
因此Babel将其转换为ES5目标的polyfill。 我很困惑为什么TypeScript不能像其他ES6功能那样做同样的事情。