Reputation: 529
I'm new to TypeScript and failed to make the errors go away. Tried a lot of things and assign any
to wherever I can but I'm still getting the following errors:
(9,7): Type '(props: IRendererProps & { children?: ReactNode; }) => any[]' is not assignable to type 'StatelessComponent<IRendererProps>'.
Type 'any[]' is not assignable to type 'ReactElement<any> | null'.
Type 'any[]' is not assignable to type 'ReactElement<any>'.
Property 'type' is missing in type 'any[]'
This is how I render the component.
<Renderer
renderStart={0}
renderEnd={2}
renderWrapper={(child: any) => <h1>{child}</h1>}
>
<p>one</p>
<p>two</p>
<p>three</p>
</Renderer>
And this is how the component looks like:
import * as React from "react";
interface IRendererProps {
readonly renderStart: number;
readonly renderEnd: number;
readonly renderWrapper: (x: any) => any;
}
const Renderer: React.SFC<IRendererProps> = props => {
const { children, renderStart, renderEnd, renderWrapper } = props;
return React.Children.map(children, (child, index) => {
if (index < renderStart || index > renderEnd) {
return null;
} else {
return renderWrapper(child);
}
});
};
export default Renderer;
Does anyone know how to fix these errors?
EDIT: okay, I wrapped React.Children.map in fragments and that fixed it.
return <React.Fragment> {...array.map here...}</React.Fragment>
Upvotes: 0
Views: 374
Reputation: 2522
Basically, in React, one component, regardless it is SFC or a class component, can only return one root
node. The definition of the React.StatelessComponent
is kind of a hint for you about this.
interface StatelessComponent<P> {
(props: P & { children?: ReactNode }, context?: any): ReactElement<any> | null
}
Therefore, which your component, wrap the React.Children.map inside a single React.Element will resolve the problem, it can be either a div
, a Fragment
or whatever you prefer.
Below is an example of how to resolve your problem:
const Renderer: React.SFC<IRendererProps> = props => {
const { children, renderStart, renderEnd, renderWrapper } = props;
return (
<div>
{React.Children.map(children, (child, index) => {
if (index < renderStart || index > renderEnd) {
return null;
} else {
return renderWrapper(child);
}
})}
</div>
);
};
Upvotes: 3
Reputation: 10218
You can't return several elements at once directly. Just wrap them into React.Fragment
:
const Renderer: React.SFC<IRendererProps> = props => {
const { children, renderStart, renderEnd, renderWrapper } = props;
return <React.Fragment>
{
React.Children.map(children, (child, index) => {
if (index < renderStart || index > renderEnd) {
return null;
} else {
return renderWrapper(child);
}
})
}
</React.Fragment>;
};
Upvotes: 0