title: TypesScript wrongly assumes that property is read-only
body: <p>I have a simple react component that I created with typescript and I encountered the following strange error. Here is my code.</p>
  
  <pre><code>interface State {
    value: string
  }
  
  class App extends React.Component&lt;{}, State&gt; {
    constructor() {
      super();
      this.state = {
        value: ''
      }
    }
  
    changeHandler = (e: any) =&gt; {
      let state = Object.assign({}, this.state);
      state.value = e.target.value;
      this.setState(state);
    }
  
    render() {
      return (
        &lt;div className="App"&gt;
          &lt;input
            type="text"
            value={this.state.value}
            name="value"
            onChange={this.changeHandler} /&gt;
        &lt;/div&gt;
      );
    }
  }
  
  export default App;
  </code></pre>
  
  <p>And this is the error that I got.</p>
  
  <blockquote>
    <p>error TS2540: Cannot assign to 'value' because it is a constant or a
    read-only property.</p>
  </blockquote>
  
  <p>This error got me thinking that perhaps this was typescript's way of enforcing the rule of not mutating state. To test this theory I did the following.</p>
  
  <pre><code>this.state.value = e.target.value
  </code></pre>
  
  <p>In this case I am clearly mutating state directly and sure enough I get the same error.</p>
  
  <p>Then I had the idea of changing my interface to this.</p>
  
  <pre><code>interface State {
    value: Ivalue
  }
  
  interface Ivalue {
    value: string;
  }
  </code></pre>
  
  <p>And then I refactored my component to use this new interface like this.</p>
  
  <pre><code>class App extends React.Component&lt;{}, State&gt; {
    constructor() {
      super();
      this.state = {
        value: {
          value: ''
        }
      }
    }
  
    changeHandler = (e: any) =&gt; {
      let value = Object.assign({}, this.state.value);
      value.value = e.target.value;
      this.setState({value});
    }
  
    render() {
      return (
        &lt;div className="App"&gt;
          &lt;input
            type="text"
            value={this.state.value.value}
            name="value"
            onChange={this.changeHandler} /&gt;
        &lt;/div&gt;
      );
    }
  }
  
  export default App;
  </code></pre>
  
  <p>And sure enough this compiled! 
  My question is really 2 questions. First, why was typescript not satisfied with my copy of state, like I have in my first snippet of code where I used <code>Object.assign</code>?
  Second, why does nesting my state object one level further down solve this issue?</p>