首页 > 解决方案 > 为什么 TypeScript 中未定义剩余参数?

问题描述

我有一个使用 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 核心/运行时 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');

标签: javascripttypescriptreact-nativebabeljs

解决方案


为什么它没有正确转译,我该如何解决?(我在 Babel 核心/运行时 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具有您期望的值。


推荐阅读