<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I tried using the <code class="notranslate">@types/react-redux</code> package and had problems.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I tried using the latest stable version of tsc. <a href="https://www.npmjs.com/package/typescript" rel="nofollow">https://www.npmjs.com/package/typescript</a></li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have a question that is inappropriate for <a href="https://stackoverflow.com/" rel="nofollow">StackOverflow</a>.  (Please ask any appropriate questions there).</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> <a href="https://github.com/blog/821-mention-somebody-they-re-notified">Mention</a> the authors (see <code class="notranslate">Definitions by:</code> in <code class="notranslate">index.d.ts</code>) so they can respond.
<ul dir="auto">
<li>Authors: <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/tkqubo/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/tkqubo">@tkqubo</a>, <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/seansfkelley/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/seansfkelley">@seansfkelley</a> <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/thasner/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/thasner">@thasner</a></li>
</ul>
</li>
</ul>
<p dir="auto">When using <code class="notranslate">connect()</code> in a React.Component, it loses its props when creating the element using TSX.</p>
<p dir="auto">for example:</p>
<div class="highlight highlight-source-tsx notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import React from 'react'
import { connect } from 'react-redux'
import { State } from '../actions'

export interface RemoteFilterProps {
  name: string;
  access: string;
  group: string;
  onSelect: FilterProps['onSelect'];
}

export class RemoteFilter extends React.Component&lt;RemoteFilterProps, RemoteFilterState&gt; {
  /* ... */
}

export default connect((state: State): Partial&lt;RemoteFilterProps&gt; =&gt; {
  return {
    access: state.access
  }
})(RemoteFilter)"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-smi">React</span> <span class="pl-k">from</span> <span class="pl-s">'react'</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">connect</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'react-redux'</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-smi">State</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'../actions'</span>

<span class="pl-k">export</span> <span class="pl-k">interface</span> <span class="pl-smi">RemoteFilterProps</span> <span class="pl-kos">{</span>
  <span class="pl-c1">name</span>: <span class="pl-smi">string</span><span class="pl-kos">;</span>
  <span class="pl-c1">access</span>: <span class="pl-smi">string</span><span class="pl-kos">;</span>
  <span class="pl-c1">group</span>: <span class="pl-smi">string</span><span class="pl-kos">;</span>
  <span class="pl-c1">onSelect</span>: <span class="pl-smi">FilterProps</span><span class="pl-kos">[</span><span class="pl-s">'onSelect'</span><span class="pl-kos">]</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">export</span> <span class="pl-k">class</span> <span class="pl-smi">RemoteFilter</span> <span class="pl-k">extends</span> <span class="pl-smi">React</span><span class="pl-kos">.</span><span class="pl-c1">Component</span><span class="pl-kos">&lt;</span><span class="pl-smi">RemoteFilterProps</span><span class="pl-kos">,</span> <span class="pl-smi">RemoteFilterState</span><span class="pl-kos">&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-c">/* ... */</span>
<span class="pl-kos">}</span>

<span class="pl-k">export</span> <span class="pl-k">default</span> <span class="pl-en">connect</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">state</span>: <span class="pl-smi">State</span><span class="pl-kos">)</span>: <span class="pl-smi">Partial</span><span class="pl-kos">&lt;</span><span class="pl-smi">RemoteFilterProps</span><span class="pl-kos">&gt;</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-k">return</span> <span class="pl-kos">{</span>
    <span class="pl-c1">access</span>: <span class="pl-s1">state</span><span class="pl-kos">.</span><span class="pl-c1">access</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">RemoteFilter</span><span class="pl-kos">)</span></pre></div>
<p dir="auto">when using it, it shows no props:</p>
<div class="highlight highlight-source-tsx notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import RemoteFilter from './remotefilter'

export default (&lt;RemoteFilter /&gt;) // nothing is enforced"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-smi">RemoteFilter</span> <span class="pl-k">from</span> <span class="pl-s">'./remotefilter'</span>

<span class="pl-k">export</span> <span class="pl-k">default</span> <span class="pl-kos">(</span><span class="pl-c1">&lt;</span><span class="pl-smi">RemoteFilter</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span><span class="pl-kos">)</span> <span class="pl-c">// nothing is enforced</span></pre></div>
<p dir="auto">my work around is using:</p>
<div class="highlight highlight-source-tsx notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="export default connect((state: State) =&gt; {
  return {
    access: state.access
  }
})(RemoteFilter) as React.ComponentClass&lt;RemoteFilterProps&gt;"><pre class="notranslate"><span class="pl-k">export</span> <span class="pl-k">default</span> <span class="pl-en">connect</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">state</span>: <span class="pl-smi">State</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-k">return</span> <span class="pl-kos">{</span>
    <span class="pl-c1">access</span>: <span class="pl-s1">state</span><span class="pl-kos">.</span><span class="pl-c1">access</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">RemoteFilter</span><span class="pl-kos">)</span> <span class="pl-k">as</span> <span class="pl-smi">React</span><span class="pl-kos">.</span><span class="pl-smi">ComponentClass</span><span class="pl-kos">&lt;</span><span class="pl-smi">RemoteFilterProps</span><span class="pl-kos">&gt;</span></pre></div>
<p dir="auto">There is an issue with the react-redux typings such that if you leave out the <code class="notranslate">TOwnProps</code> parameters to both <code class="notranslate">mapStateToProps</code> and <code class="notranslate">mapDispatchToProps</code>, you can end up with a wrapped component that will freely accept any set of props (literally anything). This issue is with the newest version of react-redux as of this writing; which were last touched <a class="commit-link" data-hovercard-type="commit" data-hovercard-url="https://github.com/DefinitelyTyped/DefinitelyTyped/commit/56295f5058cac7ae458540423c50ac2dcf9fc711/hovercard" href="https://github.com/DefinitelyTyped/DefinitelyTyped/commit/56295f5058cac7ae458540423c50ac2dcf9fc711"><tt>56295f5</tt></a>.</p>
<p dir="auto">So here's a snippet that erroneously compiles fine:</p>
<div class="highlight highlight-source-tsx notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface OwnProps {
  foo: string;
}

interface ConnectedProps {
  bar: string;
}

class FooComponent extends React.Component&lt;OwnProps &amp; ConnectedProps, {}&gt; {
  render() {
    return &lt;div/&gt;;
  }
}

function mapStateToProps(state: any): ConnectedProps {
  return {
    bar: 'baz'
  };
}

const WrappedFoo = connect(mapStateToProps)(FooComponent);

// Missing `foo` but also specifying unknown property `quux`; this compiles fine.
React.createElement(WrappedFoo, { quux: 10 });"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-smi">OwnProps</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-kos">}</span>

<span class="pl-k">interface</span> <span class="pl-smi">ConnectedProps</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">FooComponent</span> <span class="pl-k">extends</span> <span class="pl-smi">React</span><span class="pl-kos">.</span><span class="pl-c1">Component</span><span class="pl-kos">&lt;</span><span class="pl-smi">OwnProps</span> <span class="pl-c1">&amp;</span> <span class="pl-smi">ConnectedProps</span><span class="pl-kos">,</span> <span class="pl-kos">{</span><span class="pl-kos">}</span><span class="pl-kos">&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-en">render</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-c1">&lt;</span><span class="pl-ent">div</span><span class="pl-c1">/</span><span class="pl-c1">&gt;</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span>

<span class="pl-k">function</span> <span class="pl-en">mapStateToProps</span><span class="pl-kos">(</span><span class="pl-s1">state</span>: <span class="pl-smi">any</span><span class="pl-kos">)</span>: <span class="pl-smi">ConnectedProps</span> <span class="pl-kos">{</span>
  <span class="pl-k">return</span> <span class="pl-kos">{</span>
    <span class="pl-c1">bar</span>: <span class="pl-s">'baz'</span>
  <span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">const</span> <span class="pl-smi">WrappedFoo</span> <span class="pl-c1">=</span> <span class="pl-en">connect</span><span class="pl-kos">(</span><span class="pl-s1">mapStateToProps</span><span class="pl-kos">)</span><span class="pl-kos">(</span><span class="pl-smi">FooComponent</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">// Missing `foo` but also specifying unknown property `quux`; this compiles fine.</span>
<span class="pl-smi">React</span><span class="pl-kos">.</span><span class="pl-en">createElement</span><span class="pl-kos">(</span><span class="pl-smi">WrappedFoo</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">quux</span>: <span class="pl-c1">10</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">You can work around it by typecasting the result of <code class="notranslate">connect</code>, and everything works as expected:</p>
<div class="highlight highlight-source-tsx notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="const WrappedFoo = connect(mapStateToProps)(FooComponent) as React.ComponentClass&lt;OwnProps&gt;;"><pre class="notranslate"><span class="pl-k">const</span> <span class="pl-smi">WrappedFoo</span> <span class="pl-c1">=</span> <span class="pl-en">connect</span><span class="pl-kos">(</span><span class="pl-s1">mapStateToProps</span><span class="pl-kos">)</span><span class="pl-kos">(</span><span class="pl-smi">FooComponent</span><span class="pl-kos">)</span> <span class="pl-k">as</span> <span class="pl-smi">React</span><span class="pl-kos">.</span><span class="pl-smi">ComponentClass</span><span class="pl-kos">&lt;</span><span class="pl-smi">OwnProps</span><span class="pl-kos">&gt;</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">Or you can mention <code class="notranslate">OwnProps</code> in <code class="notranslate">mapStateToProps</code>:</p>
<div class="highlight highlight-source-tsx notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function mapStateToProps(state: any, ownProps: OwnProps): ConnectedProps {
  return {
    bar: 'baz'
  };
}

const WrappedFoo = connect(mapStateToProps)(FooComponent);"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">mapStateToProps</span><span class="pl-kos">(</span><span class="pl-s1">state</span>: <span class="pl-smi">any</span><span class="pl-kos">,</span> <span class="pl-s1">ownProps</span>: <span class="pl-smi">OwnProps</span><span class="pl-kos">)</span>: <span class="pl-smi">ConnectedProps</span> <span class="pl-kos">{</span>
  <span class="pl-k">return</span> <span class="pl-kos">{</span>
    <span class="pl-c1">bar</span>: <span class="pl-s">'baz'</span>
  <span class="pl-kos">}</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">const</span> <span class="pl-smi">WrappedFoo</span> <span class="pl-c1">=</span> <span class="pl-en">connect</span><span class="pl-kos">(</span><span class="pl-s1">mapStateToProps</span><span class="pl-kos">)</span><span class="pl-kos">(</span><span class="pl-smi">FooComponent</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">A couple definitions:</p>
<ul dir="auto">
<li><code class="notranslate">OwnProps</code>: This is the type of the parameters that the connected version of the component accepts. That is, those that the parent must provide that aren’t auto-injected.</li>
<li><code class="notranslate">ConnectedProps</code>: This is the type of the parameters that are selected by <code class="notranslate">mapStateToProps</code>. It’s not strictly necessary to the typings or the workaround, but it helps clarify when debugging since it allows you to properly type <code class="notranslate">mapStateToProps</code>.</li>
</ul>
<p dir="auto">What I think is happening here is that when the optional <code class="notranslate">TOwnProps</code> seen in the signature of <code class="notranslate">mapStateToProps</code> and <code class="notranslate">mapDispatchToProps</code> is absent (as it is in the example), Typescript falls back on inferring <code class="notranslate">TOwnProps</code> as <code class="notranslate">{}</code>. The output of the whole process (after running <code class="notranslate">connect</code>) thus ends up as <code class="notranslate">React.ComponentClass&lt;{}&gt;</code>, at which point all bets are off, since <code class="notranslate">{}</code> accepts anything and everything.</p>
<p dir="auto">For similar reasons, you also shouldn't specify something very lenient for <code class="notranslate">OwnProps</code>, such as the empty interface, which is functionally identical to <code class="notranslate">{}</code>. The only workaround for explicitly specifying "no own props" as far as I can tell is to use the typecast method to cast it to <code class="notranslate">React.ComponentClass&lt;void&gt;</code> (though probably with an intermediate <code class="notranslate">any</code> cast, since Typescript doesn't accept the <code class="notranslate">void</code> cast).</p>
<p dir="auto">I tried to tweak the typings to fix this, but I wasn't able to find a better way to define <code class="notranslate">TOwnProps</code>. Thoughts, <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/tkqubo/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/tkqubo">@tkqubo</a> (as the listed maintainer)?</p>