6

I am trying to learn typescript and to be quite honest I am having a hell of a time wrapping my head around this. I understand that this question has been asked COUNTLESS times before but I cannot for the life of me figure out how to translate the answers that I'm reading to my own code. Something which doesn't help is a lot of the answers I seem to find use a different syntax to write components than I have been using. Anyways any help is GREATLY appreciated because I am completely lost here. I have literally only two files, App.tsx and DisplayPerson.tsx

Inside my App.tsx file I have this code:

import React from 'react';
import DisplayPerson from './components/DisplayPerson';

export interface Person {
    firstName: string;
    lastName: string;
}

function App() {
    const person1: Person = {
        firstName: 'fname',
        lastName: 'lname',
    };

    return (
        <div>
            <DisplayPerson person={person1} />
        </div>
    );
}

export default App;

And inside my DisplayPerson.tsx file I have:

import React from 'react';
import { Person } from '../App';

export default function DisplayPerson({ person }: Person) {
    return (
        <div>
            <h1>person.firstName</h1>
            <h1>person.lastName</h1>
        </div>
    );
}

In DisplayPerson.tsx I have an error which says "Property 'person' does not exist on type 'Person'". I tried to fix this by changing my Person interface to:

export interface Person {
    person : {
        firstName: string;
        lastName: string;
    }
}

And the declaration of my person1 const to this:

const person1: Person = {
        person: {
            firstName: 'fname',
            lastName: 'lname',
        },
    };

Which did solve the error in DisplayPerson.tsx, however I now have an error in App.tsx which says "Type 'Person' is missing the following properties from type '{ firstName: string; lastName: string;}': firstName, lastName. The expected type comes from property 'person' which was declared here on type 'IntrinsicAttributes & Person"

This is when I tried googling my issue and frankly I just cannot figure out what's wrong even without googling. Any help is greatly appreciated and if you could also explain why what I've done does not work I would love that a lot.

Thank you so much!

MrBabalafe
  • 120
  • 1
  • 1
  • 7

3 Answers3

7

You need to correct your props part. So your DisplayPerson.tsx file will be like this

import React from 'react';
import { Person } from '../App';

interface IProps {
   person: Person
}
export default function DisplayPerson({ person }: IProps) {
    return (
        <div>
            <h1>{person.firstName}</h1>
            <h1>{person.lastName}</h1>
        </div>
    );
}

Update:

In React, the structure is like below for Functional component

function DisplayPerson(props) {}

as you see here props is a parameter that is of type object. so you need to pass an object. Now you want a person as a key inside that object which is Object deconstruction. That's why it has to be done like #1 from the answer of Nathan.
You can refer this: https://javascript.info/destructuring-assignment#object-destructuring

Chirag Shah
  • 464
  • 5
  • 9
5

I think you have a couple small issues in DisplayPerson.tsx. I've fixed them in this codesandbox: https://codesandbox.io/s/modest-snyder-s5bmt?file=/src/App.tsx

DisplayPerson.tsx:

import React from 'react';
import { Person } from '../App';

export default function DisplayPerson({ person }: { person: Person }) {
    return (
        <div>
            <h1>{person.firstName}</h1>
            <h1>{person.lastName}</h1>
        </div>
    );
}
  1. Your prop type is incorrect. Instead of { person }: Person you should have { person }: { person: Person }.
  2. You should wrap person.firstName and person.lastName with {}

To elaborate on #1: The props passed into DisplayPerson is an object where the key is the prop name and the value is whatever's passed in. Therefore, the type of the props object isn't Person but rather an object with key person and a value of type Person.

Nathan
  • 1,321
  • 1
  • 18
  • 32
  • Thank you this did work! Could you please explain why I need to do #1? What exactly does "{person: Person}" do after already saying {person}? – MrBabalafe Jul 05 '21 at 05:59
  • I have given you an update on your question on my answer. As it's not much readable here. Please have a look at that. – Chirag Shah Jul 05 '21 at 06:11
  • 1
    Thank you Chirag. I appreciate the link and your answer in the thread as well – MrBabalafe Jul 05 '21 at 06:14
3

I have found the issue, you are not passing the parameters as props. You have to do it, I have fixed it:

App.tsx

import React from 'react';
import DisplayPerson from './components/DisplayPerson';

export interface Person {
    firstName: string;
    lastName: string;
}

function App() {
    const person1: Person = {
        firstName: 'fname',
        lastName: 'lname',
    };

    return (
        <div>
            <DisplayPerson person={person1} />
        </div>
    );
}

export default App;

DisplayPerson.tsx

import React from 'react';
import { Person } from '../App';

export default function DisplayPerson(props:{person:Person}) {

    return (
        <div>
            <h1>{props.person.firstName}</h1>
            <h1>{props.person.lastName}</h1>
        </div>
    );
}
Pranava Mohan
  • 533
  • 2
  • 8
  • 18