Map class property assertion fails when using babel-plugin-transform-runtime
- Dominant language
- JavaScript
- Stars
- 797
- Forks
- 49
- PR merge metrics
- No merged PRs in 30d
Description
[](https://oss.issuehunt.io/r/gajus/flow-runtime/issues/177)
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
```js
// @flow
// @flow-runtime assert, annotate
class Foo {
bar: Map = 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:
```js
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).
```js
'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](https://oss.issuehunt.io/u/issuehunt) ($50.00)
### Submitted pull Requests
- [#286 Fix class property refs for transformed builtins](https://oss.issuehunt.io/r/gajus/flow-runtime/pull/286)
- [#298 fix: align Map runtime type reference with transform-runtime](https://oss.issuehunt.io/r/gajus/flow-runtime/pull/298)
- [#308 Fix Map assertions with babel transform-runtime](https://oss.issuehunt.io/r/gajus/flow-runtime/pull/308)
---
#### [Become a backer now!](https://oss.issuehunt.io/r/gajus/flow-runtime/issues/177)
#### [Or submit a pull request to get the deposits!](https://oss.issuehunt.io/r/gajus/flow-runtime/issues/177)
### Tips
- Checkout the [Issuehunt explorer](https://oss.issuehunt.io/r/gajus/flow-runtime/) to discover more funded issues.
- Need some help from other developers? [Add your repositories](https://oss.issuehunt.io/r/new) on IssueHunt to raise funds.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.