The error "Property 'children' does not exist on type 'y' occurs when we pass children to a component which does not have the children prop type defined.

error

Problem

The following code will recreate the same error as above:

type BioProps = {  //πŸ‘ˆ
  name: string;
  location: string;
};

const Bio = (props: BioProps) => {
  return (
    <div>
      <h1>Name: {props.name}</h1>
      <h1>Location: {props.location}</h1>
      {props.children}  //πŸ‘ˆ
    </div>
  );
};

const App = () => {
  return (
    <div>
      <Bio name="James Doe" location="Germany">  //πŸ‘ˆ
        <h1>Age: 21</h1>
      </Bio>
    </div>
  );
};

export default App;
error code

Here, we are using a component called 'Bio' to display the 'name' and 'location' of a person. However, we are also passing a child component to the 'Bio' component by wrapping it inside the 'Bio' opening and closing tag.

Solution

In this case, the error occurs since we forgot to mention the prop type of children being passed to the 'Bio' component. We can fix this by passing the proper typing for the children prop of the component 'Bio'.


type BioProps = {  
  name: string;
  location: string;
  children: React.ReactNode //πŸ‘ˆ
};

const Bio = (props: BioProps) => {
  return (
    <div>
      <h1>Name: {props.name}</h1>
      <h1>Location: {props.location}</h1>
      {props.children}  
    </div>
  );
};

const App = () => {
  return (
    <div>
      <Bio name="James Doe" location="Germany">  
        <h1>Age: 21</h1>
      </Bio>
    </div>
  );
};

export default App;
solution code

In case, you didn't intend to pass any children to the component, then you should use a self-closing tag like in the following code.


type BioProps = {
  name: string;
  location: string;
};

const Bio = (props: BioProps) => {
  return (
    <div>
      <h1>Name: {props.name}</h1>
      <h1>Location: {props.location}</h1>
    </div>
  );
};

const App = () => {
  return (
    <div>
      <Bio name="James Doe" location="Germany" />  //πŸ‘ˆ
    </div>
  );
};

export default App;
no children code
You need to use an opening and closing tag only when passing children to a component.

Bonus Tips

You can use other coding practices like destructuring the props to avoid accessing the 'props' object each and every time, or passing an 'any' type to the prop to disable type checking altogether. See the code below:

const Bio = ({ name, location, children }: any) => {  //πŸ‘ˆ
  return (
    <div>
      <h1>Name: {name}</h1>
      <h1>Location: {location}</h1>
      {children}
    </div>
  );
};

const App = () => {
  return (
    <div>
      <Bio name="James Doe" location="Germany">
        <h1>Age: 21</h1>
      </Bio>
    </div>
  );
};

export default App;
prop restructuring and any typeΒ 

To have more strong type checking, it is common to use the 'React.FucntionalComponent' type when defining a component. This is to ensure that the return of the React component is also type checked.

type BioProps = {
  name: string;
  location: string;
  children: React.ReactNode;
};

const Bio: React.FunctionComponent<BioProps> = ({ name, location, children }) => {
  return (
    <div>
      <h1>Name: {name}</h1>
      <h1>Location: {location}</h1>
      {children}
    </div>
  );
};

const App = () => {
  return (
    <div>
      <Bio name="James Doe" location="Germany">
        <h1>Age: 21</h1>
      </Bio>
    </div>
  );
};

export default App;
React.FunctionalComponent

This ensures that the return type is a React functional component.

Check my article on why to use TypeScript with React?

TypeScript with ReactJS ?
In this article, you’ll learn all you require to know to begin using TypeScript and React, and more critically we’ll discuss why or why you should not utilize this. There’s a decent case to be made for both sides of that argument.