codemix / babel-plugin-typecheck

Static and runtime type checking for JavaScript in the form of a Babel plugin.
MIT License
886 stars 44 forks source link

`Invalid assignment` error since `3.9.0 ` release #148

Closed dtothefp closed 7 years ago

dtothefp commented 8 years ago

This error started popping up yesterday coinciding with a Babel 6.9.0 release, but I'm not sure the two are related. Here is the error I'm receiving:

ERROR in ./index.js
Module build failed: SyntaxError: /typecheck-demo/index.js:Invalid assignment value for "this.hasLoadedOnce".

Expected:
false

Got:
true
  19 |
  20 |   markAsLoadedOnce: function() {
> 21 |     this.hasLoadedOnce = true;
     |     ^
  22 |   },
  23 |
  24 |   /**

for a code block without any type checking:

import _ from 'lodash';
import Backbone from 'backbone';
import 'backbone-validation';

const Base = Backbone.Model.extend({

  /**
   * Used when parsing a model to support a root-level key.
   *
   * @property {String} payloadRootName
   */
  payloadRootName: '',

  hasLoadedOnce: false,

  initialize: function(options) {
    this.listenToOnce(this, 'change', this.markAsLoadedOnce);
  },

  markAsLoadedOnce: function() {
    this.hasLoadedOnce = true;
  },

  /**
   * Provides basic parsing for model instances.
   *
   * Implements behavior of `payloadRootName`.
   *
   * @param  {Object} payload Raw JSON-parsed payload.
   * @return {Object}
   */
  parse: function(payload) {
    const root = this.payloadRootName;
    return root && _.has(payload, root) ? payload[root] : payload;
  },

  /**
   * Generates a view-ready copy of the model.
   *
   * By default, this is identical to `toJSON`, but should be overridden
   * to provide custom behavior.
   *
   * @return {Object}
   */
  toView: function() {
    return Backbone.Model.prototype.toJSON.apply(this, arguments);
  },
  /**
   * Easily get tag props by name
   * @param {String}
   * @returns {*}
   */
  getTag: function(tagName) {
    return _.get(this.attributes, 'tags.' + tagName, '');
  },

  setTag: function(tagName, value) {
    if (!this.attributes.tags) {
      this.attributes.tags = {};
    }
    this.attributes.tags[tagName] = value;
  },

  substituteString: function(str, replacements) {
    return str.replace(/%\w+%/g, function(all) {
      return replacements[all] || all;
    });
  }
});

_.extend(Base.prototype, Backbone.Validation.mixin);

export default Base;

I made a sample repo demonstrating the issue using typecheck 3.9.0 https://github.com/dtothefp/typecheck-babel-demo

And a branch with a working build on typecheck 3.8.0 https://github.com/dtothefp/typecheck-babel-demo/tree/babel-6.9.0-typecheck-3.8.0

prewk commented 8 years ago

We're getting it on babel 6.5.2 and babel-plugin-typecheck 3.9.0

prewk commented 8 years ago

If it's not obvious already, it seems that it interprets this:

{
  hasLoadedOnce: false
}

As a type declaration for hasLoadedOnce instead of a variable assignment on the object, thus forcing it to only accept false as value.

Switching back to 3.8.0 solved the problem for us.

phpnode commented 7 years ago

Hi, sorry for taking so long to respond to this, this project is now deprecated in favour of https://codemix.github.io/flow-runtime which aims for full compatibility with Flow.

I checked and babel-plugin-flow-runtime does not have this particular bug.