Reputation: 1181
Trying to get better with Typescript in React
I have a super simple app where I have App.tsx
with a useState for an array of objects
import List from './components/List';
interface IState{
name: string
age: number
}
function App() {
const [people, setpeople] = useState<IState[]>([
{
name: 'Chris',
age: 20
},
{
name: 'John',
age: 28
},
{
name: 'Paul',
age: 23
}
])
return (
<div className="App">
<List people={people}/>
</div>
);
}
export default App;
I want to pass this as a prop into another component List.tsx
.
interface IProps{
name: string
age: number
}
const List = (people:IProps[]) => {
return (
<div>
{people.map(person => (
<h2>{person.name}</h2>
))}
</div>
);
};
export default List;
I have types for the object in App.tsx
and I'm trying to use the same types in List.tsx
The problem in App.tsx
at <List people={people}/>
on people I get
Type '{ people: IState[]; }' is not assignable to type 'IntrinsicAttributes & IProps[]'.
Property 'people' does not exist on type 'IntrinsicAttributes & IProps[]'
How do I pass the data in the prop with types ?
Upvotes: 2
Views: 6334
Reputation: 46291
One way to fix your issue is to export the IState
from App.tsx
and import in List
, and use it like so:
import { IState } from "../App"; // use the corect path
interface IProps {
people: IState;
}
const List = ({ people }: IProps) => {
return (
<div>
{people.map((person) => (
<h2>{person.name}</h2>
))}
</div>
);
};
export default List;
Here is how you would export the interface in App.tsx
:
export interface IState{
name: string
age: number
}
Upvotes: 0
Reputation: 66228
That is because props
is the top level object that contains all props passed into the component, so you should either destructure it, or change the interface:
Quick fix: destructure props
const List = ({ people }: { people: IProps[] }) => { ... }
Better fix: Change the typing of IProps
so It defines the nested people
key
interface IProps{
people: Array<{
name: string;
age: number;
}>
}
const List = ({ people }: IProps) => { ... }
Some additional tip: instead of declaring the same prop interface across two files, which means you need to update them in multiple locations should you change your mind later, you can always make List
export the people
prop (or actually, the atomised version, say IPerson
) and then let the consuming parent import it instead. An example:
// List.tsx
export interface IPerson {
name: string;
age: number;
}
interface IProps {
people: IPerson[];
}
const List = ({ people }: IProps) => { ... }
Then...
// App.tsx
import List, { IPerson } from './components/List';
const [people, setpeople] = useState<IPerson[]>([ ... ]);
Upvotes: 5
Reputation: 1423
You can export your interface in the first file, and then import it in the second file
export interface IState{
name: string
age: number
}
And the to use the same interface in List.tsx.,
import { IState} from './List';
Upvotes: 1