我有一个正在使用TypeScript(3.6.3)进行编程的React Native应用程序。我有以下代码(实际代码来自API库,但这是最小的可复制示例):
class Base{
someVal: string[];
constructor() {
this.someVal = [];
}
someMethod<T extends Base>(this: T, ...someArgs:string[]){
debugger;
this.someVal = someArgs;
}
}
class Derived extends Base{
}
let myVar = new Derived().someMethod('hello');
该代码完全模仿库代码,并且行为相同(错误)。没有编译器错误或警告。运行代码时,我希望someArgs
为['hello']
,但它为undefined
。另外,我有一个arguments
数组,其中包含['hello']
的实际值:
此时,代码(由Babel即时翻译)的行为就像Javascript(因此,未定义的实际变量和幻像参数变量)。为什么它不能正确编译,我该如何解决? (我使用的是Babel Core /运行时7.6.2)
这是生成的index.bundle
中的相关代码:
var Base = function () {
function Base() {
(0, _classCallCheck2.default)(this, Base);
this.someVal = [];
}
(0, _createClass2.default)(Base, [{
key: "someMethod",
value: function someMethod() {
debugger;
for (var _len = arguments.length, someArgs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
someArgs[_key - 1] = arguments[_key];
}
this.someVal = someArgs;
}
}]);
return Base;
}();
var Derived = function (_Base) {
(0, _inherits2.default)(Derived, _Base);
function Derived() {
(0, _classCallCheck2.default)(this, Derived);
return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Derived).apply(this, arguments));
}
return Derived;
}(Base);
var myVar = new Derived().someMethod('hello');
为什么它不能正确地进行翻译,我该如何解决? (我使用的是Babel Core /运行时7.6.2)
代码被“正确地”编译,因为它在执行时将正常运行,但是如您所见,它的行为与使用调试器检查输出代码时所期望的不一样。不幸的是,这没有简单的方法。
someMethod<T extends Base>(this: T, ...someArgs:string[]){
debugger;
this.someVal = someArgs;
}
成为
value: function someMethod() {
debugger;
for (var _len = arguments.length, someArgs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
someArgs[_key - 1] = arguments[_key];
}
this.someVal = someArgs;
}
因为Babel将生成someArgs
数组的时间延迟到使用该数组之前的最后一刻(在这种情况下,是分配给它的)。在这种情况下,最终是after
您的debugger
语句。这样做是因为函数中可能有一些分支从未真正使用过someArgs
,如果从未使用过该数组,则将arguments
转换为数组会浪费性能。
如果您进入调试器,直到到达this.someVal = someArgs;
行,您会看到someArgs
具有您所期望的值。
显然,这确实是Babel错误,其开放的PR尚未合并到母版中:https://github.com/babel/babel/pull/9714:
TypeScript“此参数”是伪参数,不应为计算功能参数时要考虑在内。这个补丁通过使用来自transform-typescript的条件来跳过它插件。
注意:由于transform-typescript插件正在删除这种参数,包括在transform-parameters插件求解之前问题。此补丁可以解决其他情况下的问题。