Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Passing Typescript interface props to a child component returns not existing properties

I understand how to assign prop types using TypeScript. But I am not able to pass down the interface prop checking down to another component.

Error:

Property 'comments' does not exist on type 'ArticleProps'.ts(2339)

Tried adding it but still no luck. Thought that If you are inside the parent component that if you create a component and pass the data that it would work the same, but TypeScript obviously doesn’t like this.

export interface ArticleProps {
  page: {
    _id: string;
    _createdAt: string;
    comments: Comment[];
    body: any;
    publishedAt: string;
    title: string;
    featuredImage: {
      asset?: string;
      alt?: string;
    };
    author: {
      name: string;
      featuredImage: {
        alt?: string;
      };
    };
  };
}

export interface Comment {
  name: string;
  approved: boolean;
  comment: string;
  email: string;
  article: {
    _ref: string;
    _type: string;
  };
  _createdAt: string;
  _id: string;
  _rev: string;
  _type: string;
  _updatedAt: string;
}

Comments.tsx:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import { dateFormat } from "@lib/helpers";
import { Comment, ArticleProps } from "types/article";

import { FC } from "react";

const Comments: FC<ArticleProps> = ({ comments }: ArticleProps) => (
  <>
    {comments.length > 0 && (
      <div className="flex flex-col my-10">
        <h3 className="text-4xl">Comments</h3>
        <hr className="mt-2 mb-5 border-2 border-yellow-500" />
        {comments.map(({ name, _id, _createdAt, comment }: Comment) => (
          <div className="px-4 py-6 bg-white rounded-sm shadow-md" key={_id}>
            <p>
              <time className="block text-sm font-bold">
                {dateFormat(_createdAt)}
              </time>
              <span className="text-bubblegum">{name}</span> :
              <span className="pl-2">{comment}</span>
            </p>
          </div>
        ))}
      </div>
    )}
  </>
);

export default Comments;

index.tsx:

{/* Comments */}
<Comments comments={comments} />

>Solution :

ArticleProps doesn’t have a comments property. It has a page property that has a comments property, but it doesn’t have its own comments property.

If you want Comments to receive the comments that would be on an ArticleProps instance (as you seem to from your usage <Comments comments={comments} />), you could define that like this:

const Comments: FC<{comments: Comment[]}> = ({ comments }) => (

or without FC (some say it’s not best practice):

const Comments = ({ comments }: {comments: Comment[]}) => (

Instead of Comment[] there, you could use ArticleProps["page"]["comments"] so that the type would follow the type of comments on page of ArticleProps.

Sometimes that’s appropriate, but it seems overkill in that example.

const Comments: FC<{comments: ArticleProps["page"]["comments"]}> = ({ comments }) => (
// or without `FC`:
const Comments = ({ comments }: {comments: ArticleProps["page"]["comments"]}) => (

Or Pick<ArticleProps["page"], "comments">:

const Comments: FC<Pick<ArticleProps["page"], "comments">> = ({ comments }) => (
    <div>{comments}</div>
);
// or without `FC`:
const Comments = ({ comments }: Pick<ArticleProps["page"], "comments">) => (
    <div>{comments}</div>
);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading