<h2 dir="auto">Bug Report</h2>
<p dir="auto"><strong>Current Behavior</strong><br>
Unable to use <code class="notranslate">Immutable.Record</code>'s getter methods.</p>
<p dir="auto"><strong>Input Code</strong></p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="mkdir /tmp/test &amp;&amp; cd /tmp/test &amp;&amp; npm init
npm i -S @babel/cli @babel/core @babel/preset-env @babel/preset-flow @babel/plugin-proposal-class-properties immutable@4.0.0-rc.10"><pre class="notranslate">mkdir /tmp/test <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">cd</span> /tmp/test <span class="pl-k">&amp;&amp;</span> npm init
npm i -S @babel/cli @babel/core @babel/preset-env @babel/preset-flow @babel/plugin-proposal-class-properties immutable@4.0.0-rc.10</pre></div>
<p dir="auto">(save the following as <code class="notranslate">main.js</code>)</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// @flow

import Immutable from &quot;immutable&quot;;

class T extends Immutable.Record({ items: Immutable.List() }) {
  items: Immutable.List&lt;number&gt;;
}

console.log(new T().items, new T().get(&quot;items&quot;));"><pre class="notranslate"><span class="pl-c">// <span class="pl-k">@flow</span></span>

<span class="pl-k">import</span> <span class="pl-v">Immutable</span> <span class="pl-k">from</span> <span class="pl-s">"immutable"</span><span class="pl-kos">;</span>

<span class="pl-k">class</span> <span class="pl-v">T</span> <span class="pl-k">extends</span> <span class="pl-v">Immutable</span><span class="pl-kos">.</span><span class="pl-en">Record</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">items</span>: <span class="pl-v">Immutable</span><span class="pl-kos">.</span><span class="pl-en">List</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-c1">items</span>: <span class="pl-c1">Immutable</span><span class="pl-kos">.</span><span class="pl-c1">List</span><span class="pl-c1">&lt;</span><span class="pl-c1">number</span><span class="pl-c1">&gt;</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-k">new</span> <span class="pl-v">T</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">items</span><span class="pl-kos">,</span> <span class="pl-k">new</span> <span class="pl-v">T</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s">"items"</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><strong>Expected behavior/code</strong><br>
The expected behavior is for the generated code to not break getter methods on <code class="notranslate">Immutable.Record</code> attributes. <code class="notranslate">main.js</code> (above) works as expected when compilation is carried out as given below:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./node_modules/.bin/babel --no-babelrc --presets @babel/env --presets @babel/flow main.js|node"><pre class="notranslate">./node_modules/.bin/babel --no-babelrc --presets @babel/env --presets @babel/flow main.js<span class="pl-k">|</span>node</pre></div>
<p dir="auto">... which produces:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="List [] List []"><pre class="notranslate"><code class="notranslate">List [] List []
</code></pre></div>
<p dir="auto">(<code class="notranslate">new T().items</code> getter works)</p>
<p dir="auto">However, when the proposal-class-properties plugin is used, the getter on the <code class="notranslate">Immutable.Record</code> instance no longer works:</p>
<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="./node_modules/.bin/babel --no-babelrc --presets @babel/env --presets @babel/flow --plugins @babel/plugin-proposal-class-properties main.js|node"><pre class="notranslate">./node_modules/.bin/babel --no-babelrc --presets @babel/env --presets @babel/flow --plugins @babel/plugin-proposal-class-properties main.js<span class="pl-k">|</span>node</pre></div>
<p dir="auto">Produces:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="undefined List []"><pre class="notranslate"><code class="notranslate">undefined List []
</code></pre></div>
<p dir="auto"><strong>Babel Configuration (.babelrc, package.json, cli command)</strong></p>
<p dir="auto">No <code class="notranslate">.babelrc</code> used. <code class="notranslate">package.json</code> below:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;name&quot;: &quot;test&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;description&quot;: &quot;&quot;,
  &quot;main&quot;: &quot;main.js&quot;,
  &quot;directories&quot;: {
    &quot;test&quot;: &quot;test&quot;
  },
  &quot;scripts&quot;: {
    &quot;test&quot;: &quot;echo \&quot;Error: no test specified\&quot; &amp;&amp; exit 1&quot;
  },
  &quot;author&quot;: &quot;&quot;,
  &quot;license&quot;: &quot;ISC&quot;,
  &quot;dependencies&quot;: {
    &quot;@babel/cli&quot;: &quot;^7.1.0&quot;,
    &quot;@babel/core&quot;: &quot;^7.1.0&quot;,
    &quot;@babel/plugin-proposal-class-properties&quot;: &quot;^7.1.0&quot;,
    &quot;@babel/preset-env&quot;: &quot;^7.1.0&quot;,
    &quot;@babel/preset-flow&quot;: &quot;^7.0.0&quot;,
    &quot;immutable&quot;: &quot;^4.0.0-rc.10&quot;
  }
}"><pre class="notranslate"><span class="pl-kos">{</span>
  <span class="pl-s">"name"</span>: <span class="pl-s">"test"</span><span class="pl-kos">,</span>
  <span class="pl-s">"version"</span>: <span class="pl-s">"1.0.0"</span><span class="pl-kos">,</span>
  <span class="pl-s">"description"</span>: <span class="pl-s">""</span><span class="pl-kos">,</span>
  <span class="pl-s">"main"</span>: <span class="pl-s">"main.js"</span><span class="pl-kos">,</span>
  <span class="pl-s">"directories"</span>: <span class="pl-kos">{</span>
    <span class="pl-s">"test"</span>: <span class="pl-s">"test"</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-s">"scripts"</span>: <span class="pl-kos">{</span>
    <span class="pl-s">"test"</span>: <span class="pl-s">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-s">"author"</span>: <span class="pl-s">""</span><span class="pl-kos">,</span>
  <span class="pl-s">"license"</span>: <span class="pl-s">"ISC"</span><span class="pl-kos">,</span>
  <span class="pl-s">"dependencies"</span>: <span class="pl-kos">{</span>
    <span class="pl-s">"@babel/cli"</span>: <span class="pl-s">"^7.1.0"</span><span class="pl-kos">,</span>
    <span class="pl-s">"@babel/core"</span>: <span class="pl-s">"^7.1.0"</span><span class="pl-kos">,</span>
    <span class="pl-s">"@babel/plugin-proposal-class-properties"</span>: <span class="pl-s">"^7.1.0"</span><span class="pl-kos">,</span>
    <span class="pl-s">"@babel/preset-env"</span>: <span class="pl-s">"^7.1.0"</span><span class="pl-kos">,</span>
    <span class="pl-s">"@babel/preset-flow"</span>: <span class="pl-s">"^7.0.0"</span><span class="pl-kos">,</span>
    <span class="pl-s">"immutable"</span>: <span class="pl-s">"^4.0.0-rc.10"</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto"><strong>Environment</strong></p>
<ul dir="auto">
<li>Babel version(s): v7.1.0</li>
<li>Node/npm version: Node 8.12.0</li>
<li>OS: Linux</li>
<li>Monorepo: N/A</li>
<li>How you are using Babel: cli</li>
</ul>
<p dir="auto"><strong>Possible Solution</strong><br>
N/A</p>
<p dir="auto"><strong>Additional context/Screenshots</strong><br>
N/A</p>
<h2 dir="auto">Bug Report</h2>
<p dir="auto"><strong>Current Behavior</strong></p>
<p dir="auto"><code class="notranslate">@babel/plugin-proposal-class-properties</code> transform flow type annotation to a property assigning undefined.</p>
<p dir="auto">this may caught statement order unexpected error.</p>
<p dir="auto"><strong>Input Code</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="let code = `
class B {}
class Logger extends B {
  log: {
    error: boolean
  }
  silent: boolean
  log = {
    error: true
  }
  get silent(): boolean {
    return this._silent;
  }
  set silent(val: boolean) {
    this._silent = !!val;
    if (!this.log) {
      throw new Error('#log should not be nil.')
    }
    Object.keys(this.log).forEach(k =&gt; { /* do something... */  })
  }
  constructor() {
    super()
  }
}
`

let r = require(&quot;@babel/core&quot;).transform(code, {
  &quot;presets&quot;: [ &quot;@babel/preset-flow&quot; ],
  &quot;plugins&quot;: [
    [ &quot;@babel/plugin-proposal-class-properties&quot;, { &quot;loose&quot;: true } ]
  ]
})
console.log(r.code)"><pre class="notranslate"><span class="pl-k">let</span> <span class="pl-s1">code</span> <span class="pl-c1">=</span> <span class="pl-s">`</span>
<span class="pl-s">class B {}</span>
<span class="pl-s">class Logger extends B {</span>
<span class="pl-s">  log: {</span>
<span class="pl-s">    error: boolean</span>
<span class="pl-s">  }</span>
<span class="pl-s">  silent: boolean</span>
<span class="pl-s">  log = {</span>
<span class="pl-s">    error: true</span>
<span class="pl-s">  }</span>
<span class="pl-s">  get silent(): boolean {</span>
<span class="pl-s">    return this._silent;</span>
<span class="pl-s">  }</span>
<span class="pl-s">  set silent(val: boolean) {</span>
<span class="pl-s">    this._silent = !!val;</span>
<span class="pl-s">    if (!this.log) {</span>
<span class="pl-s">      throw new Error('#log should not be nil.')</span>
<span class="pl-s">    }</span>
<span class="pl-s">    Object.keys(this.log).forEach(k =&gt; { /* do something... */  })</span>
<span class="pl-s">  }</span>
<span class="pl-s">  constructor() {</span>
<span class="pl-s">    super()</span>
<span class="pl-s">  }</span>
<span class="pl-s">}</span>
<span class="pl-s">`</span>

<span class="pl-k">let</span> <span class="pl-s1">r</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">"@babel/core"</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">transform</span><span class="pl-kos">(</span><span class="pl-s1">code</span><span class="pl-kos">,</span> <span class="pl-kos">{</span>
  <span class="pl-s">"presets"</span>: <span class="pl-kos">[</span> <span class="pl-s">"@babel/preset-flow"</span> <span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-s">"plugins"</span>: <span class="pl-kos">[</span>
    <span class="pl-kos">[</span> <span class="pl-s">"@babel/plugin-proposal-class-properties"</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-s">"loose"</span>: <span class="pl-c1">true</span> <span class="pl-kos">}</span> <span class="pl-kos">]</span>
  <span class="pl-kos">]</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span>
<span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">r</span><span class="pl-kos">.</span><span class="pl-c1">code</span><span class="pl-kos">)</span></pre></div>
<p dir="auto">ouput =&gt;</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class B {}

class Logger extends B {
  get silent() {
    return this._silent;
  }

  set silent(val) {
    this._silent = !!val;

    if (!this.log) {
      throw new Error('#log should not be nil.')   // &lt;----- will throw if the annotation property assigning undefined
    }

    Object.keys(this.log).forEach(k =&gt; { /* do something... */ });
    });
  }

  constructor() {
    super();
    this.log = void 0;  &lt;&lt;&lt;&lt;&lt;----
    this.silent = void 0; &lt;&lt;&lt;&lt;&lt;---- with setter defined.
    this.log = {
      error: true
    };
  }
}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">B</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>

<span class="pl-k">class</span> <span class="pl-v">Logger</span> <span class="pl-k">extends</span> <span class="pl-v">B</span> <span class="pl-kos">{</span>
  <span class="pl-k">get</span> <span class="pl-en">silent</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">return</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">_silent</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  <span class="pl-k">set</span> <span class="pl-en">silent</span><span class="pl-kos">(</span><span class="pl-s1">val</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">_silent</span> <span class="pl-c1">=</span> <span class="pl-c1">!</span><span class="pl-c1">!</span><span class="pl-s1">val</span><span class="pl-kos">;</span>

    <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">log</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
      <span class="pl-k">throw</span> <span class="pl-k">new</span> <span class="pl-v">Error</span><span class="pl-kos">(</span><span class="pl-s">'#log should not be nil.'</span><span class="pl-kos">)</span>   <span class="pl-c">// &lt;----- will throw if the annotation property assigning undefined</span>
    <span class="pl-kos">}</span>

    <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">keys</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">log</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">forEach</span><span class="pl-kos">(</span><span class="pl-s1">k</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span> <span class="pl-c">/* do something... */</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos"></span> <span class="pl-kos">{</span>
    <span class="pl-smi">super</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">log</span> <span class="pl-c1">=</span> <span class="pl-k">void</span> <span class="pl-c1">0</span><span class="pl-kos">;</span>  <span class="pl-c1">&lt;</span><span class="pl-c1">&lt;&lt;</span><span class="pl-c1">&lt;&lt;</span><span class="pl-c1">--</span><span class="pl-c1">--</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">silent</span> <span class="pl-c1">=</span> <span class="pl-k">void</span> <span class="pl-c1">0</span><span class="pl-kos">;</span> <span class="pl-c1">&lt;</span><span class="pl-c1">&lt;&lt;</span><span class="pl-c1">&lt;&lt;</span><span class="pl-c1">--</span><span class="pl-c1">--</span> <span class="pl-s1">with</span> <span class="pl-s1">setter</span> <span class="pl-s1">defined</span><span class="pl-kos">.</span>
    <span class="pl-c1">this</span><span class="pl-kos">.</span><span class="pl-c1">log</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
      <span class="pl-c1">error</span>: <span class="pl-c1">true</span>
    <span class="pl-kos">}</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto"><strong>Expected behavior/code</strong></p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class B {}

class Logger extends B {
  get silent() {
    return this._silent;
  }

  set silent(val) {
    this._silent = !!val;

    if (!this.log) {
      throw new Error('#log should not be nil.')
    }

    Object.keys(this.log).forEach(k =&gt; { /* do something... */ });
  }

  constructor() {
    super();
    this.log = {
      error: true
    };
  }

}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">B</span> <span class="pl-kos">{</span><span class="pl-kos">}</span>

<span class="pl-k">class</span> <span class="pl-v">Logger</span> <span class="pl-k">extends</span> <span class="pl-v">B</span> <span class="pl-kos">{</span>
  <span class="pl-k">get</span> <span class="pl-en">silent</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-k">return</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">_silent</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  <span class="pl-k">set</span> <span class="pl-en">silent</span><span class="pl-kos">(</span><span class="pl-s1">val</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">_silent</span> <span class="pl-c1">=</span> <span class="pl-c1">!</span><span class="pl-c1">!</span><span class="pl-s1">val</span><span class="pl-kos">;</span>

    <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-c1">!</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">log</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
      <span class="pl-k">throw</span> <span class="pl-k">new</span> <span class="pl-v">Error</span><span class="pl-kos">(</span><span class="pl-s">'#log should not be nil.'</span><span class="pl-kos">)</span>
    <span class="pl-kos">}</span>

    <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">keys</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">log</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">forEach</span><span class="pl-kos">(</span><span class="pl-s1">k</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span> <span class="pl-c">/* do something... */</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">super</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">log</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
      <span class="pl-c1">error</span>: <span class="pl-c1">true</span>
    <span class="pl-kos">}</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

<span class="pl-kos">}</span></pre></div>
<p dir="auto"><strong>Environment</strong></p>
<ul dir="auto">
<li>Babel version(s): [e.g. v6.0.0, v7.0.0-beta.55]</li>
<li>Node/npm version: [e.g. Node 8/npm 5]</li>
<li>OS: [e.g. OSX 10.13.4]</li>
<li>Monorepo [e.g. yes/no/Lerna]</li>
<li>How you are using Babel: <code class="notranslate">js</code></li>
</ul>
<p dir="auto"><strong>Possible Solution</strong></p>
<p dir="auto">Should strip the <code class="notranslate">ClassProperty</code> type of <code class="notranslate">TypeAnnotation</code>.</p>