<p dir="auto">[x] Many common issues and suggestions are addressed in the FAQ<br>
<a href="https://github.com/Microsoft/TypeScript/wiki/FAQ">https://github.com/Microsoft/TypeScript/wiki/FAQ</a><br>
[x] Search for duplicates before logging new issues<br>
<a href="https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=is%3Aissue">https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&amp;q=is%3Aissue</a><br>
[x] Questions are best asked and answered at Stack Overflow<br>
<a href="http://stackoverflow.com/questions/tagged/typescript" rel="nofollow">http://stackoverflow.com/questions/tagged/typescript</a></p>
<hr>
<p dir="auto">-&gt; asked on S/O here <a href="http://stackoverflow.com/questions/37189910/react-stateless-component-children-with-typescript-error-property-children" rel="nofollow">http://stackoverflow.com/questions/37189910/react-stateless-component-children-with-typescript-error-property-children</a> no responses so far.</p>
<p dir="auto"><strong>TypeScript Version:</strong><br>
1.8.2</p>
<p dir="auto"><strong>Code</strong></p>
<div class="highlight highlight-source-tsx notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// presentational components
const MsgDisplay = ({msg}) =&gt; (
  &lt;div&gt;
    {msg} // will be more complicated later
  &lt;/div&gt;)

const RowDisplay = ({data, children}) =&gt; (
  &lt;tr&gt;
    &lt;td&gt;...&lt;/td&gt;
    &lt;td&gt;{ children }&lt;/td&gt;
    &lt;td&gt;...&lt;/td&gt;
  &lt;/tr&gt;)

// container component
public render() {
    return (
      &lt;RowDisplay data={this.props.xyz} &gt;
        &lt;MsgDisplay msg={someMsg} /&gt;
      &lt;/RowDisplay&gt;
    )
  }"><pre class="notranslate"><span class="pl-c">// presentational components</span>
<span class="pl-k">const</span> <span class="pl-smi">MsgDisplay</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-kos">{</span>msg<span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span>
  <span class="pl-c1">&lt;</span><span class="pl-ent">div</span><span class="pl-c1">&gt;</span>
    <span class="pl-kos">{</span><span class="pl-s1">msg</span><span class="pl-kos">}</span> // will be more complicated later
  <span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">div</span><span class="pl-c1">&gt;</span><span class="pl-kos">)</span>

<span class="pl-k">const</span> <span class="pl-smi">RowDisplay</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-kos">{</span>data<span class="pl-kos">,</span> children<span class="pl-kos">}</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span>
  <span class="pl-c1">&lt;</span><span class="pl-ent">tr</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">td</span><span class="pl-c1">&gt;</span>...<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">td</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">td</span><span class="pl-c1">&gt;</span><span class="pl-kos">{</span> <span class="pl-s1">children</span> <span class="pl-kos">}</span><span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">td</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">td</span><span class="pl-c1">&gt;</span>...<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">td</span><span class="pl-c1">&gt;</span>
  <span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">tr</span><span class="pl-c1">&gt;</span><span class="pl-kos">)</span>

<span class="pl-c">// container component</span>
<span class="pl-en">public</span> <span class="pl-s1">render</span><span class="pl-kos">(</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-kos">(</span>
      <span class="pl-c1">&lt;</span><span class="pl-smi">RowDisplay</span> <span class="pl-c1">data</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">props</span><span class="pl-kos">.</span><span class="pl-c1">xyz</span><span class="pl-kos">}</span> <span class="pl-c1">&gt;</span>
        <span class="pl-c1">&lt;</span><span class="pl-smi">MsgDisplay</span> <span class="pl-c1">msg</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-s1">someMsg</span><span class="pl-kos">}</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
      <span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-smi">RowDisplay</span><span class="pl-c1">&gt;</span>
    <span class="pl-kos">)</span>
  <span class="pl-kos">}</span></pre></div>
<p dir="auto"><strong>Expected behavior:</strong></p>
<p dir="auto">Should compile.</p>
<p dir="auto"><strong>Actual behavior:</strong></p>
<p dir="auto">Complains that <code class="notranslate">error TS2324: Property 'children' is missing in type 'IntrinsicAttributes &amp; { data: any; children: any; }'.</code></p>
<p dir="auto">Seems it can't see the children being passed in jsx notation.</p>
<h2 dir="auto">Rationale</h2>
<p dir="auto">Props are an important part of a React component's interface, but children can be as well.<br>
In applications it's not uncommon to want to restrict what kind of children a component will<br>
accept. Currently this enforcement has to be done at runtime by throwing errors.</p>
<h2 dir="auto">The Goal</h2>
<p dir="auto">Components can specify allowed children as a union type. Each member would correspond to<br>
the tag, or 'type' field, of the resulting Element. Ideally this could be plucked from<br>
the type of props.children, which would satisfy both component classes and SFCs.</p>
<h2 dir="auto">Motivating Examples:</h2>
<p dir="auto">A modal component may want to make assumptions about its children to satisfy layout<br>
constraints.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface IModalProps {
    children: ModalHeader | ModalBody | ModalFooter;
}

function Modal({ children }: IModalProps) { ... }
function ModalHeader(props) { ... }
function ModalBody(props) { ... }
function ModalFooter(props) { ... }

&lt;Modal&gt;
    &lt;ModalHeader /&gt;
    &lt;div /&gt; { /* Desired error: type 'div' does not exist in type 'ModalHeader | ModalBody | ModalFooter' */ }
    &lt;ModalBody /&gt;
    &lt;ModalFooter /&gt;
&lt;/Modal&gt;"><pre class="notranslate"><span class="pl-s1">interface</span> <span class="pl-v">IModalProps</span> <span class="pl-kos">{</span>
    children: <span class="pl-v">ModalHeader</span> <span class="pl-c1">|</span> <span class="pl-v">ModalBody</span> <span class="pl-c1">|</span> <span class="pl-v">ModalFooter</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">function</span> <span class="pl-v">Modal</span><span class="pl-kos">(</span><span class="pl-kos">{</span> children <span class="pl-kos">}</span>: <span class="pl-v">IModalProps</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-v">ModalHeader</span><span class="pl-kos">(</span><span class="pl-s1">props</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-v">ModalBody</span><span class="pl-kos">(</span><span class="pl-s1">props</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-v">ModalFooter</span><span class="pl-kos">(</span><span class="pl-s1">props</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> ... <span class="pl-kos">}</span>

<span class="pl-c1">&lt;</span><span class="pl-ent">Modal</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">ModalHeader</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</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-c">/* Desired error: type 'div' does not exist in type 'ModalHeader | ModalBody | ModalFooter' */</span> <span class="pl-kos">}</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">ModalBody</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">ModalFooter</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">Modal</span><span class="pl-c1">&gt;</span></pre></div>
<p dir="auto">Similarly...</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface IButtonGroupProps {
    children: 'button';
}

function ButtonGroup({ children }: IButtonGroupProps) { ... }

&lt;ButtonGroup&gt;
    &lt;button /&gt;
    &lt;button /&gt;
    &lt;a href='' /&gt; { /* Desired error: type 'a' is not assignable to type 'button' */ }
&lt;/ButtonGroup&gt;"><pre class="notranslate"><span class="pl-s1">interface</span> <span class="pl-v">IButtonGroupProps</span> <span class="pl-kos">{</span>
    children: <span class="pl-s">'button'</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">function</span> <span class="pl-v">ButtonGroup</span><span class="pl-kos">(</span><span class="pl-kos">{</span> children <span class="pl-kos">}</span>: <span class="pl-v">IButtonGroupProps</span><span class="pl-kos">)</span> <span class="pl-kos">{</span> ... <span class="pl-kos">}</span>

<span class="pl-c1">&lt;</span><span class="pl-ent">ButtonGroup</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">button</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">button</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-ent">a</span> <span class="pl-c1">href</span><span class="pl-c1">=</span><span class="pl-s">''</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span> <span class="pl-kos">{</span> <span class="pl-c">/* Desired error: type 'a' is not assignable to type 'button' */</span> <span class="pl-kos">}</span>
<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">ButtonGroup</span><span class="pl-c1">&gt;</span></pre></div>
<p dir="auto">An interesting emerging pattern is using JSX as a function call to turn imperative APIs into<br>
declarative ones. Currently these 'render callbacks' can't be type-checked at all. A more complete<br>
summary can be found at <a href="http://reactpatterns.com/#render-callback" rel="nofollow">http://reactpatterns.com/#render-callback</a>. A further example can be found at <a href="https://github.com/ReactTraining/react-media#usage">https://github.com/ReactTraining/react-media#usage</a>.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface IUser {
    Name: string;
}

interface IFetchUserProps {
    children(user: IUser): any;
}

class FetchUser extends React.Component&lt;IFetchUserProps, any&gt; {
    render() {
        return this.state
            ? this.props.children(this.state.result)
            : null;
    }

    componentDidMount() {
        api.fetchUser().then(result =&gt; this.setState({ result }));
    }
}

function UserName() {
    return (
        &lt;FetchUser&gt;
            { user =&gt; (
                &lt;h1&gt;{ user.NAme }&lt;/h1&gt; // Desired error: property 'NAme' does not exist on type 'IUser'
            ) }
        &lt;/FetchUser&gt;
    );
}"><pre class="notranslate"><span class="pl-s1">interface</span> <span class="pl-v">IUser</span> <span class="pl-kos">{</span>
    Name: <span class="pl-s1">string</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-s1">interface</span> <span class="pl-v">IFetchUserProps</span> <span class="pl-kos">{</span>
    <span class="pl-c1">children</span><span class="pl-kos">(</span><span class="pl-s1">user</span>: <span class="pl-v">IUser</span><span class="pl-kos">)</span>: <span class="pl-s1">any</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">class</span> <span class="pl-v">FetchUser</span> <span class="pl-k">extends</span> <span class="pl-v">React</span><span class="pl-kos">.</span><span class="pl-c1">Component</span><span class="pl-c1">&lt;</span><span class="pl-v">IFetchUserProps</span><span class="pl-kos">,</span> <span class="pl-s1">any</span><span class="pl-c1">&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-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">state</span>
            ? <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">props</span><span class="pl-kos">.</span><span class="pl-en">children</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-kos">.</span><span class="pl-c1">result</span><span class="pl-kos">)</span>
            : <span class="pl-c1">null</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span>

    <span class="pl-en">componentDidMount</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
        <span class="pl-s1">api</span><span class="pl-kos">.</span><span class="pl-en">fetchUser</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">then</span><span class="pl-kos">(</span><span class="pl-s1">result</span> <span class="pl-c1">=&gt;</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> result <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-s1">function</span> <span class="pl-v">UserName</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-c1">return</span> <span class="pl-kos">(</span>
        <span class="pl-c1">&lt;</span><span class="pl-v">FetchUser</span><span class="pl-c1">&gt;</span>
            <span class="pl-kos">{</span> <span class="pl-s1">user</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span>
                <span class="pl-c1">&lt;</span><span class="pl-s1">h1</span><span class="pl-c1">&gt;</span><span class="pl-kos">{</span> user<span class="pl-kos">.</span><span class="pl-v">NAme</span> <span class="pl-kos">}</span><span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-s1">h1</span><span class="pl-c1">&gt;</span> <span class="pl-c">// Desired error: property 'NAme' does not exist on type 'IUser'</span>
            <span class="pl-kos">)</span> <span class="pl-kos">}</span>
        <span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-v">FetchUser</span><span class="pl-c1">&gt;</span>
    <span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">Lastly, I don't <em>think</em> any of this is necessarily specific to React. Other libraries leveraging the JSX<br>
specification for component structure should be able to leverage this as well. The crux of this lies at<br>
the relationship between the type of the 'children' attribute of a given tag and the children actually<br>
passed to it at usage sites.</p>