Home > Enterprise >  Container doesn't allow type children typescript
Container doesn't allow type children typescript

Time:02-02

Container is component extended from @material-ui/core and it doesn't accept children with type React.ReactNode.

Layout.tsx:

import { Container } from "@material-ui/core";

type LayoutProps = {
  children: React.ReactNode;
};

function Layout({ children }: LayoutProps) {
  return (
    <div>
      <Container>{children}</Container>
    </div>
  );
}

It works when, Container is replaced with a div tag. So, the issue is with MaterialUI's Container.

The only fix I found was to edit the internal Container code and,

-    children: NonNullable<React.ReactNode>;
     children?: React.ReactNode;

But changing internal Container code run into some issue later in future.

Is there any other way to fix this ?

The type error I get now is,

No overload matches this call.
  Overload 1 of 2, '(props: { component: ElementType<any>; } & { children: boolean | ReactChild | ReactFragment | ReactPortal; disableGutters?: boolean | undefined; fixed?: boolean | undefined; maxWidth?: false | ... 5 more ... | undefined; } & CommonProps<...> & Pick<...>): Element', gave the following error.
    Type 'ReactNode' is not assignable to type 'boolean | ReactChild | ReactFragment | ReactPortal'.
      Type 'undefined' is not assignable to type 'boolean | ReactChild | ReactFragment | ReactPortal'.
  Overload 2 of 2, '(props: DefaultComponentProps<ContainerTypeMap<{}, "div">>): Element', gave the following error.
    Type 'ReactNode' is not assignable to type 'boolean | ReactChild | ReactFragment | ReactPortal'.ts(2769)
Container.d.ts(6, 5): The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & { component: ElementType<any>; } & { children: boolean | ReactChild | ReactFragment | ReactPortal; disableGutters?: boolean | undefined; fixed?: boolean | undefined; maxWidth?: false | ... 5 more ... | undefined; } & CommonProps<...> & Pick<...>'
Container.d.ts(6, 5): The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & { children: boolean | ReactChild | ReactFragment | ReactPortal; disableGutters?: boolean | undefined; fixed?: boolean | undefined; maxWidth?: false | ... 5 more ... | undefined; } & CommonProps<...> & Pick<...>'

CodePudding user response:

It does accept React.ReactNode, but the type also contains null and undefined. It is a union type of the following:

ReactChild | ReactFragment | ReactPortal | boolean | null | undefined

The NonNullable<React.ReactNode> simply ensures that null/undefined is not passed in, so it will have a type of:

ReactChild | ReactFragment | ReactPortal | boolean

You simply have to assert that children is not null/undefined, otherwise just pass in an empty string:

<Container>{children ?? ''}</Container>
  •  Tags:  
  • Related