[TS] IntrinsicAttributes & (props) is not assignable to type ... 에러

2024. 8. 6. 22:22Frontend/JS

에러 발생

CardSection 컴포넌트로 posts props 를 넘기는 과정에서 발생한 문제.

CardSection 역시 동일한 타입의 props 를 선언했지만 아래와 같은 에러가 발생했다.

 

 

MainBlog.tsx (부모 컴포넌트)

posts 변수를 CardSection 컴포넌트의 props 로 전달한다.

해당 변수의 타입은 CardInterface[] 배열이다.

export interface CardInterface {
  name: string;
  role: string;
}

const MainBlog = () => {
  const posts: CardInterface[] = [
    {name: 'Post1', role: 'CEO BALENCIAGA'},
    {name: 'Post2', role: 'CEO REBORN & YELLOW OCTOPUS'}
  ];
  return (
    <section className={styles.teamSection}>
      <div className={styles.underlineTitle}>
        <p>Posts</p>
      </div>
      <CardSection posts = {posts}/>
    </section>
  )
}

export default MainBlog;

 

 

CardSection.tsx (자식 컴포넌트)

CardSection 은 posts prop 을 부모로 부터 전달받으며 타입은 CardInterface[] 배열로 선언돼 있다.

부모 컴포넌트에서도 CardInterface[] 타입을 넘겨주기 때문에 왜 에러가 발생하는지 쉽게 이해되지 않았다.

const CardSection = (posts: CardInterface[]) => {
  return (
    <div className={styles.teamGrid}>
      {posts.map((member, index) => (
        <div key={member.name}
             className={styles.teamMember}
        >
          <div className={styles.underlineTitle}>
            <h3>{member.name}</h3>
          </div>
          <FlipCard
            frontImage={`/team-member-${index + 1}.jpeg`}
            altText={member.name}
            backContent={
              <div>
                <h4>{member.name}</h4>
                <p>{member.role}</p>
              </div>
            }
            width={400}
            height={600}
          />
        </div>
      ))}
    </div>
  );
}

export default CardSection;

 

 

 

해결

props 를 간단히 구조분해(destructuring) 하여 에러를 해결할 수 있다.

에러의 원인은 하위 컴포넌트로 전달하는 props 의 타입을 지정하지 않았기 때문이다.

엥 분명 CardInterface[] 로 타입을 지정했는데 이게 무슨 말일까?

리액트 컴포넌트에서는 Prop 을 넘길 때 인수 객체 자체가 전달된다.

즉 보내고자 한 prop 이 아래와 같다면,

[
    {
      "name": "Post1",
      "role": "CEO BALENCIAGA"
    }
]

 

function CardSection(posts: CardInterface[])로 받을 때 posts 의 모습은 아래와 같기 때문이다.

{
  "posts": [
    {
      "name": "Post1",
      "role": "CEO BALENCIAGA"
    }
  ]
}

 

내가 보내고자 한 객체는 이미 posts 를 필드로 한 객체 형태로 넘어오기 때문이다.

이는 리액트 컴포넌트의 props 전달 방식과 관련이 있다.

리액트는 컴포넌트에 단일 props 객체를 전달하기 때문에 이 객체는 부모 컴포넌트에서 전달한 모든 속성을 포함한다.

위 코드의 경우엔 posts 라는 속성을 포함하는 셈이다.

 

때문에 posts 를 구조분해(destructuring) 하여 컴포넌트 props 에 선언하면 에러를 해결할 수 있다.

 

변경된 코드

const CardSection = ({posts}: { posts: CardInterface[] }) => {
  return (
    <div className={styles.teamGrid}>
      {posts.map((member, index) => (
        <div key={member.name}
             className={styles.teamMember}
        >
          <div className={styles.underlineTitle}>
            <h3>{member.name}</h3>
          </div>
          <FlipCard
            frontImage={`/team-member-${index + 1}.jpeg`}
            altText={member.name}
            backContent={
              <div>
                <h4>{member.name}</h4>
                <p>{member.role}</p>
              </div>
            }
            width={400}
            height={600}
          />
        </div>
      ))}
    </div>
  );
}

export default CardSection;