Reputation: 26085
I have a component with no props other than children
, i.e.:
function Foo({ children }: React.PropsWithChildren<>) {}
React.PropsWithChildren
requires an argument. If I do React.PropsWithChildren<{}>
, Eslint produces Don't use `{}` as a type. `{}` actually means "any non-nullish value".
.
I'm using this for the empty object type:
type EmptyObj = { [k: string]: never };
However, React.PropsWithChildren<EmptyObj>
causes:
Type '{ children: Element; }' is not assignable to type 'EmptyObj'.
Property 'children' is incompatible with index signature.
Type 'Element' is not assignable to type 'never'.
What should I pass to React.PropsWithChildren
?
Edit:
I know I can just do:
function Foo({ children }: { children?: React.ReactNode }) {}
However, I'm using React.PropsWithChildren
throughout the codebase, so I'd prefer to keep it consistent.
Upvotes: 29
Views: 22995
Reputation: 6240
I was in the same situation and decided to go with:
PropsWithChildren<unknown>
Update:
See Jorrit's comment below, but React is making that the default for PropsWithChildren, which is now defined as type PropsWithChildren<P = unknown> ...
. That means we can simplify the example below to:
const MyComponent = ({ children }: PropsWithChildren) => { /* ... */ }
We're declaring a component that accepts children, but we don't know (or don't care) about other props it may have.
Example:
const MyComponent = ({ children }: PropsWithChildren<unknown>) => { /* ... */ }
// ...
<MyComponent>
<span>children</span>
</MyComponent>
Why not the FC type?
The use of the FC
type is discouraged. You can read more about it in this PR: https://github.com/facebook/create-react-app/pull/8177
Upvotes: 29
Reputation: 35
Do you know and have you defined the types of children that the FC will be taking? If so, could you not just have a union type that is passed in as the child prop value?
type FooChildren = ChildTypeOne | ChildTypeTwo | ChildTypeThree;
type FooProps = { children?: FooChildren[] };
function Foo({ children }: React.PropsWithChildren<FooProps>) {}
Also, isn't ReactChildren
an interface itself? Why not use that in the function argument?
Upvotes: 1
Reputation: 959
The solution is:
function Foo({ children }: React.PropsWithChildren<Record<never, any>>) {}
If eslint warns you about type any
use Record<never, never>
instead.
Upvotes: 28
Reputation: 10885
You can just leverage the FC
type as follows:
const Foo: FC = ({ children }) => {
return <div>{children}</div>;
};
If you really want to stick to PropsWithChildren
, then use PropsWithChildren<unknown>
instead of PropsWithChildren<{}>
. The warning you get comes from typescript-eslint
and can be turned off for those cases as another option.
Upvotes: 6
Reputation: 53874
Looking at how React.FC<>
implemented you can try:
interface WrapperProps<> {}
function App(props: React.PropsWithChildren<WrapperProps>) {
return <div>{props.children}...</div>;
}
Upvotes: 0