I have a TS problem where the JS-version of the code works, but I can't get the types to compile.
I've tried to simplify it for this question. Hopefully I didn't remove too much that'll have an effect on the answer.
So, simplified, I'm trying to write a component, <Set>
that takes another component as a prop, and wraps that around the children of <Set>
. Additionally I want all props passed to <Set>
to be passed along to the component passed as a prop.
This is the code
import React, { ReactElement, ReactNode } from "react";
interface WtProps {
children: ReactNode;
}
type WrapperType<WTProps extends WtProps> = (
props: WTProps
) => ReactElement | null;
interface SetProps<P extends WtProps> {
wrap: WrapperType<P>;
children: ReactNode;
[x: string]: unknown;
}
export function Set<WProps extends WtProps>(props: SetProps<WProps>) {
const { wrap, children, ...rest } = props;
return React.createElement(wrap, rest, children);
}
interface WrapperProps {
children: ReactNode;
foo: string;
}
const ChildWrapper: React.FC<WrapperProps> = ({ foo, children }) => {
return (
<div>
<h1>ChildWrapper</h1>
<p>{foo}</p>
{children}
</div>
);
};
export default function App() {
return (
<Set<WrapperProps> wrap={ChildWrapper} foo="value">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some happen!</h2>
</Set>
);
}
Here's a codesandbox link: https://codesandbox.io/s/musing-feynman-3euuu?file=/src/App.tsx
I've tried a bunch of different solutions, but this is what I have now. And the error I'm getting is on, the rest
parameter
return React.createElement(wrap, rest, children);
It says
No overload matches this call.
The last overload gave the following error.
Argument of type '{ [x: string]: unknown; }' is not assignable to parameter of type 'Attributes & WProps'.
Type '{ [x: string]: unknown; }' is not assignable to type 'WProps'.
'WProps' could be instantiated with an arbitrary type which could be unrelated to '{ [x: string]: unknown; }'.ts(2769)
index.d.ts(292, 14): The last overload is declared here.
I've read this question+answer How to fix TS2322: "could be instantiated with a different subtype of constraint 'object'"? so I think I know why I'm getting the error, but I don't know what to do about it.
What do I need to change to make it compile?
EDIT: I can "fix" it by making the wrap
prop have type any
, but I don't want to do that. I want stricter types. But anyway, here it is with any
https://codesandbox.io/s/pedantic-nobel-x790n