I have a component that gets used multiple times in succession with some identical properties and some unique properties:
interface InsideComponentProps {
repeatedThing: string;
uniqueThing: string;
}
const InsideComponent: React.SFC<InsideComponentProps> = ({ repeatedThing, uniqueThing }) => (
<div>{repeatedThing} - {uniqueThing}</div>
);
const Example = () => (
<div>
<InsideComponent repeatedThing="foo" uniqueThing="1" />
<InsideComponent repeatedThing="foo" uniqueThing="2" />
<InsideComponent repeatedThing="foo" uniqueThing="3" />
</div>
);
The duplicate repeatedThing
properties bother me, so I'm seeking a way to remove that redundancy. One thing I've done in non-TypeScript applications is to introduce a wrapper component that clones all of the children, adding the repeated properties in the process:
interface OutsideComponentProps {
repeatedThing: string;
}
const OutsideComponent: React.SFC<OutsideComponentProps> = ({ repeatedThing, children }) => (
<div>
{React.Children.map(children, (c: React.ReactElement<any>) => (
React.cloneElement(c, { repeatedThing })
))}
</div>
);
const Example = () => (
<OutsideComponent repeatedThing="foo">
<InsideComponent uniqueThing="1" />
<InsideComponent uniqueThing="2" />
<InsideComponent uniqueThing="3" />
</OutsideComponent>
);
The resulting JavaScript code has the behavior I want, but the TypeScript compiler has errors because I'm not passing all of the required properties when I instantiate InsideComponent
:
ERROR in [at-loader] ./src/index.tsx:27:26
TS2322: Type '{ uniqueThing: "1"; }' is not assignable to type 'IntrinsicAttributes & InsideComponentProps & { children?: ReactNode; }'.
Type '{ uniqueThing: "1"; }' is not assignable to type 'InsideComponentProps'.
Property 'repeatedThing' is missing in type '{ uniqueThing: "1"; }'.
The only solution I've thought of is to mark InsideComponent
s repeatedThing
property as optional, but that's not ideal because the value is required.
How can I preserve the strictness of making sure that InsideComponent
does actually receive all of the props while reducing the duplication of the properties at the call site?
I'm using React 16.2.0 and TypeScript 2.6.2.