I'm having trouble getting the syntax right for the Typescript React Props. I have an array of people each of which may have 0 - many cars. I have a people container that will contain all people, each person will have a car container that may contain cars, and car components that will be inside the car container.
I need to have the container for cars anyways because I will add edit buttons which will add cars to the person.
I'll add my code from top down:
PersonSlice:
export interface PersonState {
id?: number;
firstname?: string;
lastname?: string;
email?: string;
created_at?: any;
updated_at?: any;
cars?: [];
}
People.tsx:
function People() {
const people = useAppSelector(selectPerson); //person is of type interface PersonState[]
let contents;
contents = <><div className="personcontainer">
{people && people.length > 0 && people.map(person => {
return <div key={person.id}>
<Person
dispatch={dispatch}
person={person}
toggleEditForm={() => toggleEditForm(person.id)}
personToEdit={personToEdit}
submitEdit={submitEdit}
/>
</div>
})}
</div></>
});
}
This is where I start to have problems -
Person.tsx:
interface PersonProps {
dispatch: Dispatch<any>;
person: PersonState;
toggleEditForm: () => void;
submitEdit: any;
personToEdit: number;
}
function Person(props: PersonProps) {
return (
<div className="person">
<Cars cars={props.person.cars}/> //cars error: type [] | undefined not assignable to car[]
</div>
);
}
cars.tsx:
import {car, Car} from './car';
interface cars {
cars: car[];
}
function Cars (props: cars) {
return (
<div className="carcontainer">
<h2>cars container</h2>
{props.cars && props.cars.map((carobj: car) => {
<Car car={carobj} key={}/> //car error: Type '{ car: car; key: any; }' is not assignable to type 'IntrinsicAttributes & car'.
})}
</div>
)
}
export default Cars;
and finally car.tsx:
export interface car {
year: number,
make:string,
model: string,
price: number,
person_id: number,
}
export function Car (props: car) {
return (
<div className="carcontainer">
<h3>
{props.year} {props.make} {props.model} {props.price}
</h3>
</div>
)
}
So I have two errors, one in person.tsx and one in cars.tsx which I added as comments in the code.
I've read like a dozen questions on this but I'm still super confused. What am I doing wrong?
Thanks
CodePudding user response:
The fix to both issues is in cars.tsx
.
import {car, Car} from './car';
interface cars {
cars?: car[]; // make this optional since the data from PeopleState is optional
}
function Cars (props: cars) {
return (
<div className="carcontainer">
<h2>cars container</h2>
{props.cars && props.cars.map((carobj: car) => {
<Car {...carobj} key={}/> // spread carobj into the component
})}
</div>
)
}
export default Cars;
CodePudding user response:
<Cars cars={props.person.cars}/> //cars error: type [] | undefined not assignable to car[]
This isn’t really an error. You specifically wrote:
cars?: [];
This means, “I might not know where or not the person has any cars.” If you don’t, obviously you cannot render the list of cars.
Maybe you really might not know, in which case, your code should be something like:
{ props.person.cars?
<Cars cars={props.person.cars}/>
: <span>I do not know if he has cars</span> }
Or, you really know about the cars, but you might know that there are no cars, in which case you should say so:
cars: [];
In the second issue, you need to actually give it a key:
{props.cars && props.cars.map((carobj: car, idx) =>
<Car car={carobj} key={idx}/> )}