Home > Software design >  TS2559: Type '{ children: never[]; }' has no properties in common with type 'Intrinsi
TS2559: Type '{ children: never[]; }' has no properties in common with type 'Intrinsi

Time:09-11

I cant understand whats the probem is. I have already saw answers to this Error here, I saw one of the issues of others is a repetition of a function name, and not giving props to a component in the component tree. But I dont think I made those mistakes. Ill be thankfull for help :)


the Error:

TS2559: Type '{ children: never[]; }' has no properties in common with type 'IntrinsicAttributes & { post?: IPost | undefined; }'. 28 | 29 | {posts}

30 | | ^^^^ 31 | 32 | 33 |


Feed component:

import React, { useEffect, useState } from 'react';
import { Outlet } from 'react-router';
import Post from './Post';
import {List} from './List'

async function getJSON(url: string) {
  const res = await fetch(url);
  return res.json();
}

export function Feed() {
  const [posts, setPosts] = useState([{id: '', title: 'initial state'}])
  const [page, setCount] = useState(0);

  useEffect(() => {
    async function setData() {
      setPosts(await getJSON(`./data/posts.json?page=${page}`));
    }
    setData();
  }, [page])

  useEffect(() => {
    console.log('render Feed');
    console.log(posts)
  })

  return <div style={{backgroundColor:'#FAFAFA'}}> 
    <List>
      {posts}
      <Post>
        
      </Post>
    </List>
    {/* <Post>
  
    </Post> */}
    <p>
      <button onClick={() => setCount(page   1)}>Page {page}</button>
    </p>
  </div>

}


Post component:

import React, { useEffect, useState } from 'react';
import { Link, useParams } from "react-router-dom";
import {List} from './List'

async function getJSON(url: string) {
  const res = await fetch(url);
  return res.json();
}

interface IPost {
  id: string;
  title: string;
}

export default function Post({ post }: { post?: IPost }) {

  const [numLikes, addLike] = useState(0);
  const [dynamicPost, setDynamicPost] = useState({ title: '', id: '' });
  const params = useParams();

  useEffect(() => {
    async function setDynamicData() {
      console.log('setDynamicData works')
      setDynamicPost(await getJSON(`./data/post.${params.postId}.json`))
    }
    if (!post) {
      setDynamicData();
    }
    console.log('post is set!')
  }, [params.postId, post]);

  return <div>
    {post ? <div>
      <PostBox>
        <h2><Link style={{color: 'black', textDecoration: 'none' }} to={`/posts/${post?.id}`}>{post?.title || dynamicPost?.title}</Link></h2>
        <p>Num likes {numLikes}</p>
        <Like onLike={() => addLike(numLikes   1)}>
          <strong>Bla bla</strong>
        </Like>
      </PostBox>
    </div> :
      <div><h2 style={{ color: "red" }}>no posts yet</h2></div>}
  </div>
}

interface IPropsLike {
  onLike: () => void;
  children: JSX.Element;
}

function Like({ onLike, children }: IPropsLike) {
  return <button onClick={onLike}>{children}</button>
}


function PostBox({ children }: { children: JSX.Element[] }) {
  return <div style={{ 
    border: '4px solid black',
     color:"black",
      marginBottom: '1em',
       width: '100%',
        textAlign: 'center'}}>
    {children}
  </div>
}

CodePudding user response:

The problem is you're giving Post child contents (a text node containing whitespace), but Post doesn't accept child content.

Here's a simpler replication:

interface IPost {
  id: string;
  title: string;
}

function Post({ post }: { post?: IPost }) {
    return <div/>;
}

//         v−−−− error here, because of the text node
const x = <Post post={{id: "x", title: "x"}}> 

</Post>;

Playground link

Either:

  1. Don't pass children to components that don't accept them:

    <Post post={/*...*/} />
    

    Playground link

    or

  2. Update Post so it accepts children:

    export default function Post({ post, children }: { post?: IPost, children: ReactNode }) {
    // −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^
    
    //         v−−−− no error here anymore, the text node is fine
    const x = <Post post={{id: "x", title: "x"}}> 
    
    </Post>;
    

    ...and render the children in Post.

    Playground link

  • Related