flow-runtime
flow-runtime copied to clipboard
Map class property assertion fails when using babel-plugin-transform-runtime
This is a:
- [x] Bug Report
- [ ] Feature Request
- [ ] Question
- [ ] Other
Which concerns:
- [x] flow-runtime
- [x] babel-plugin-flow-runtime
- [ ] flow-runtime-validators
- [ ] flow-runtime-mobx
- [ ] flow-config-parser
- [ ] The documentation website
What is the current behaviour?
Code
// @flow
// @flow-runtime assert, annotate
class Foo {
bar: Map<string, any> = new Map()
getValue(name: string) {
return this.bar.get(name)
}
}
new Foo().getValue('hello')
.babelrc
{
"presets": [["env", {"targets": {"node": "current"}}], "flow"],
"plugins": [
"transform-decorators-legacy",
["flow-runtime", {"annotate": false, "assert": false}],
"transform-runtime",
"transform-class-properties",
],
}
Erroneous error
/Users/andy/iron-pi-webapp/node_modules/flow-runtime/dist/flow-runtime.js:9331
throw error;
^
RuntimeTypeError: Default value for property Foo.bar must be an instance of Map
Expected: Map
Actual: Map
Transpiled code and explanation
babel-plugin-transform-runtime converts usage of Map to _map2.default, where _map2 is:
var _map = require('babel-runtime/core-js/map');
var _map2 = _interopRequireDefault(_map);
But babel-plugin-flow-runtime decorates the class property with a runtime reference to 'Map', which resolves to something else (depending on the environment).
'use strict';
var _defineProperty = require('babel-runtime/core-js/object/define-property');
var _defineProperty2 = _interopRequireDefault(_defineProperty);
var _map = require('babel-runtime/core-js/map');
var _map2 = _interopRequireDefault(_map);
var _dec, _dec2, _class, _desc, _value, _class2, _descriptor;
var _flowRuntime = require('flow-runtime');
var _flowRuntime2 = _interopRequireDefault(_flowRuntime);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _initDefineProp(target, property, descriptor, context) {
if (!descriptor) return;
(0, _defineProperty2.default)(target, property, {
enumerable: descriptor.enumerable,
configurable: descriptor.configurable,
writable: descriptor.writable,
value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
});
}
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
var desc = {};
Object['ke' + 'ys'](descriptor).forEach(function (key) {
desc[key] = descriptor[key];
});
desc.enumerable = !!desc.enumerable;
desc.configurable = !!desc.configurable;
if ('value' in desc || desc.initializer) {
desc.writable = true;
}
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
return decorator(target, property, desc) || desc;
}, desc);
if (context && desc.initializer !== void 0) {
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
desc.initializer = undefined;
}
if (desc.initializer === void 0) {
Object['define' + 'Property'](target, property, desc);
desc = null;
}
return desc;
}
function _initializerWarningHelper(descriptor, context) {
throw new Error('Decorating class property failed. Please ensure that transform-class-properties is enabled.');
}
// -runtime assert, annotate
let Foo = (_dec = _flowRuntime2.default.annotate(_flowRuntime2.default.class('Foo', _flowRuntime2.default.property('bar', _flowRuntime2.default.ref('Map', _flowRuntime2.default.string(), _flowRuntime2.default.any())), _flowRuntime2.default.method('getValue', _flowRuntime2.default.param('name', _flowRuntime2.default.string())))), _dec2 = _flowRuntime2.default.decorate(_flowRuntime2.default.ref('Map', _flowRuntime2.default.string(), _flowRuntime2.default.any())), _dec(_class = (_class2 = class Foo {
constructor() {
_initDefineProp(this, 'bar', _descriptor, this);
}
getValue(name) {
let _nameType = _flowRuntime2.default.string();
_flowRuntime2.default.param('name', _nameType).assert(name);
return this.bar.get(name);
}
}, (_descriptor = _applyDecoratedDescriptor(_class2.prototype, 'bar', [_dec2], {
enumerable: true,
initializer: function () {
return new _map2.default();
}
})), _class2)) || _class);
new Foo().getValue('hello');
What is the expected behaviour?
babel-plugin-flow-runtime should use functions to resolve names at runtime (e.g. _flowRuntime2.default.ref(() => Map, ...) instead of _flowRuntime2.default.ref('Map', ...), so that Babel's module transform doesn't break the reference to Map.
Which package versions are you using?
"babel-core": "^6.26.0",
"babel-plugin-flow-runtime": "^0.15.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.1",
"babel-preset-flow": "^6.23.0",
IssueHunt Summary
Backers (Total: $50.00)
issuehunt ($50.00)
Become a backer now!
Or submit a pull request to get the deposits!
Tips
- Checkout the Issuehunt explorer to discover more funded issues.
- Need some help from other developers? Add your repositories on IssueHunt to raise funds.
IssueHunt has been backed by the following sponsors. Become a sponsor
@issuehunt has funded $50.00 to this issue.
- Submit pull request via IssueHunt to receive this reward.
- Want to contribute? Chip in to this issue via IssueHunt.
- Checkout the IssueHunt Issue Explorer to see more funded issues.
- Need help from developers? Add your repository on IssueHunt to raise funds.