编译为 JavaScript 时,有没有办法在 Haxe 中为类型别名?

Is there a way to alias types in Haxe when compiling to JavaScript?

我有以下两个class:

package geometer;

class Vector2Impl {
  public var x: Float;
  public var y: Float;

  ... operations and methods...
package geometer;

@:forward(x, y)
abstract Vector2(Vector2Impl) from Vector2Impl to Vector2Impl {
  public
  function new(x: Float, y: Float) {
    this = new Vector2Impl(x, y);
  }

  ... operator overloads ...
}

我这样做是为了在 Vector2 中重载运算符。这一切在 Haxe 内部运行良好,但是,我们从 Haxe 编译到 JavaScript。我们的输出 JavaScript 然后用于 mocha 测试。

不幸的是,JS 代码中完全省略了 class 声明的 abstract(好吧,这不是 完全 正确的,但它们确实看起来类似于:

var geometer__$Vector2_Vector2_$Impl_$ = {};
geometer__$Vector2_Vector2_$Impl_$.__name__ = true;
geometer__$Vector2_Vector2_$Impl_$._new = function(x,y) {
    return new geometer_Vector2Impl(x,y);
};

因此,在我的测试中,我不得不使用 Vector2Impl 而不是 Vector2。这有点痛苦,因为 a) 它需要更多的输入,并且 b) 它暴露了 Haxe 客户端和 JavaScript 客户端之间不一致的接口。我可以处理它,但是由于 Haxe 没有完全编译出 Vector2 类型,我想知道是否有办法可以在生成的内部将 Vector2Impl 别名为 Vector2 .js 文件。这样,而不是在我的测试中执行以下操作:

'use strict';

let expect = require('chai').expect;
let library = require('../../dist/library.js');
let geometer = library.geometer;

// Unfortunately, abstract classes (Vector2) are not available in JS-land.
let Vector2Impl = geometer.Vector2Impl;

require('../nyc-reporter');

describe('Vector2Impl', function() {
  describe ('#new', function() {
    it ('should create a new Vector2Impl object', function() {
      let v = new Vector2Impl(20.5, 100.0);

      expect(v.x).to.eq(20.5);
      expect(v.y).to.eq(100.0);
    });
  });
});

我可以这样做:

'use strict';

let expect = require('chai').expect;
let library = require('../../dist/library.js');
let geometer = library.geometer;

// Unfortunately, abstract classes (Vector2) are not available in JS-land.
let Vector2 = geometer.Vector2;

require('../nyc-reporter');

describe('Vector2', function() {
  describe ('#new', function() {
    it ('should create a new Vector2 object', function() {
      let v = new Vector2(20.5, 100.0);

      expect(v.x).to.eq(20.5);
      expect(v.y).to.eq(100.0);
    });
  });
});

显然,我知道我不能在 JavaScript 中使用运算符重载,因为该语言不支持它,但如果我可以使用 Vector2Impl 中可用的所有其他方法称它为 Vector2,那就太棒了。

注意:我知道我可以这样做:

let Vector2 = geometer.Vector2Impl;

但是,如果可能的话,我宁愿客户甚至都不知道 Vector2Impl class。

您可以简单地将 Vector2DImpl 注释为 @:expose metadata:

@:expose("geometer.Vector2D")
class Vector2Impl {
    ...
}

这包括在 $hx_exports 中作为 geometer.Vector2D