我有一个正在使用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']的实际值:

javascript - 为什么在TypeScript中未定义剩余参数?-LMLPHP

此时,代码(由Babel即时翻译)的行为就像Javascript(因此,未定义的实际变量和幻像参数变量)。为什么它不能正确编译,我该如何解决? (我在Babel Core / Runtime 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 / Runtime 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具有您期望的值。

08-19 16:41