Есть ли способ для псевдонимов типов в Haxe при компиляции в JavaScript? - PullRequest
3 голосов
/ 28 марта 2019

У меня есть два следующих класса:

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 затем используется в тестах мокко.

К сожалению, объявленные abstract классы полностью исключены из кода JS (ну, это не полностью true, но они выглядят примерно так:

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);
};

Итак, в моих тестах вместо Vector2 я вынужден использовать Vector2Impl. Это немного болезненно, потому что а) требует большего набора текста и б) предоставляет непоследовательный интерфейс между клиентами 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, если это возможно.

1 Ответ

4 голосов
/ 28 марта 2019

Вы можете просто аннотировать Vector2DImpl с помощью @:expose метаданных :

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

Это включает его в $hx_exports как geometer.Vector2D.

...