<p dir="auto">Hey Typescript,</p>
<p dir="auto">React's current typing for setState (at <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/react/react.d.ts#L128">https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/react/react.d.ts#L128</a>) is somewhat wrong - it asks for type S, while the documentation (at <a href="https://facebook.github.io/react/docs/component-api.html#setstate" rel="nofollow">https://facebook.github.io/react/docs/component-api.html#setstate</a>) specifies only that:</p>
<blockquote>
<p dir="auto">The first argument can be an object (containing zero or more keys to update)...</p>
</blockquote>
<p dir="auto">That is, callers aren't required to specify <em>all</em> properties on the state, but only a subset of properties that they're updating. Unfortunately, there's currently no way to express this in the type system. People workaround this by defining type S as having all optional properties to begin with, even if some properties should be required.</p>
<p dir="auto">It'd be great if Typescript had a some type operator that, when applied to an existing type, could construct a new type where all the properties specified in the original type are optional.</p>
<p dir="auto">Example of use:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class Component&lt;S&gt; {
  setState(state: S?): void;
  // example syntax - &quot;S?&quot; is the type S but where all properties are optional
}

interface MyState {
  foo: string;
  bar: string;
}

class MyComponent extends Component&lt;MyState&gt; {
  constructor() {
    this.state = {foo: &quot;a&quot;, bar: &quot;b&quot;};
  }

  function updateFoo() {
    // this should pass
    this.setState({ foo: &quot;newFoo&quot; });

    // you can also specify that a value is of an optional type
    const updates: MyState? = {
      bar: &quot;newBar&quot;
    };
    this.setState(updates);

    // of course, properties not in the original type are still not allowed
    // this should throw &quot;'nonExistentProperty' does not exist in type 'MyState?'&quot;
    const bad: MyState? = {
      nonExistentProperty: 123
    };
  }

}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-smi">Component</span><span class="pl-c1">&lt;</span><span class="pl-smi">S</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-c1">setState</span><span class="pl-kos">(</span><span class="pl-s1">state</span>: <span class="pl-smi">S</span>?<span class="pl-kos">)</span>: <span class="pl-smi"><span class="pl-k">void</span></span><span class="pl-kos">;</span>
  <span class="pl-c">// example syntax - "S?" is the type S but where all properties are optional</span>
<span class="pl-kos">}</span>

<span class="pl-k">interface</span> <span class="pl-smi">MyState</span> <span class="pl-kos">{</span>
  <span class="pl-c1">foo</span>: <span class="pl-smi">string</span><span class="pl-kos">;</span>
  <span class="pl-c1">bar</span>: <span class="pl-smi">string</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">class</span> <span class="pl-smi">MyComponent</span> <span class="pl-k">extends</span> <span class="pl-smi">Component</span><span class="pl-kos">&lt;</span><span class="pl-smi">MyState</span><span class="pl-kos">&gt;</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">this</span><span class="pl-kos">.</span><span class="pl-c1">state</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span><span class="pl-c1">foo</span>: <span class="pl-s">"a"</span><span class="pl-kos">,</span> <span class="pl-c1">bar</span>: <span class="pl-s">"b"</span><span class="pl-kos">}</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  <span class="pl-en">function</span> <span class="pl-s1">updateFoo</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-c">// this should pass</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-en">setState</span><span class="pl-kos">(</span><span class="pl-kos">{</span> <span class="pl-c1">foo</span>: <span class="pl-s">"newFoo"</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

    <span class="pl-c">// you can also specify that a value is of an optional type</span>
    <span class="pl-k">const</span> <span class="pl-s1">updates</span>: <span class="pl-smi">MyState</span>? <span class="pl-c1">=</span> <span class="pl-kos">{</span>
      <span class="pl-c1">bar</span>: <span class="pl-s">"newBar"</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-en">setState</span><span class="pl-kos">(</span><span class="pl-s1">updates</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

    <span class="pl-c">// of course, properties not in the original type are still not allowed</span>
    <span class="pl-c">// this should throw "'nonExistentProperty' does not exist in type 'MyState?'"</span>
    <span class="pl-k">const</span> <span class="pl-s1">bad</span>: <span class="pl-smi">MyState</span>? <span class="pl-c1">=</span> <span class="pl-kos">{</span>
      <span class="pl-c1">nonExistentProperty</span>: <span class="pl-c1">123</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">Let me know if there's anything else I could clarify, thanks for your time!</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// Given:
interface Foo {
    simpleMember: number;
    optionalMember?: string;
    objectMember: X; // Where X is a inline object type, interface, or other object-like type 
}

// This:
var foo: partial Foo;
// Is equivalent to:
var foo: {simpleMember?: number, optionalMember?: string, objectMember?: X};

// And this:
var bar: deepPartial Foo;
// Is equivalent to:
var foo: {simpleMember?: number, optionalMember?: string, objectMember?: deepPartial X};"><pre class="notranslate"><span class="pl-c">// Given:</span>
<span class="pl-k">interface</span> <span class="pl-smi">Foo</span> <span class="pl-kos">{</span>
    <span class="pl-c1">simpleMember</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span>
    <span class="pl-c1">optionalMember</span>?: <span class="pl-smi">string</span><span class="pl-kos">;</span>
    <span class="pl-c1">objectMember</span>: <span class="pl-smi">X</span><span class="pl-kos">;</span> <span class="pl-c">// Where X is a inline object type, interface, or other object-like type </span>
<span class="pl-kos">}</span>

<span class="pl-c">// This:</span>
<span class="pl-k">var</span> <span class="pl-s1">foo</span>: <span class="pl-smi">partial</span> <span class="pl-smi">Foo</span><span class="pl-kos">;</span>
<span class="pl-c">// Is equivalent to:</span>
<span class="pl-k">var</span> <span class="pl-s1">foo</span>: <span class="pl-kos">{</span><span class="pl-c1">simpleMember</span>?: <span class="pl-smi">number</span><span class="pl-kos">,</span> <span class="pl-c1">optionalMember</span>?: <span class="pl-smi">string</span><span class="pl-kos">,</span> <span class="pl-c1">objectMember</span>?: <span class="pl-smi">X</span><span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-c">// And this:</span>
<span class="pl-k">var</span> <span class="pl-s1">bar</span>: <span class="pl-smi">deepPartial</span> <span class="pl-smi">Foo</span><span class="pl-kos">;</span>
<span class="pl-c">// Is equivalent to:</span>
<span class="pl-k">var</span> <span class="pl-s1">foo</span>: <span class="pl-kos">{</span><span class="pl-c1">simpleMember</span>?: <span class="pl-smi">number</span><span class="pl-kos">,</span> <span class="pl-c1">optionalMember</span>?: <span class="pl-smi">string</span><span class="pl-kos">,</span> <span class="pl-c1">objectMember</span>?: <span class="pl-smi">deepPartial</span> <span class="pl-smi">X</span><span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
<h1 dir="auto">Potential Use Cases</h1>
<ul dir="auto">
<li>Mongo Queries (<code class="notranslate">deepPartial</code>)</li>
<li><code class="notranslate">React.setState</code> (<code class="notranslate">partial</code>)</li>
</ul>