I have two different components that have one prop in common in their states, in this minimum example it will be the pictures
prop which is an array of strings:
Apartment.ts
type ApartmentType = {
landlord: string;
pictures: string[];
}
function Apartment () {
const [ apartmentData, setApartmentData ] = useState<ApartmentType>({
landlord: 'juan',
pictures: [ 'url1', 'url2' ]
})
return (
<h1>Apartment</h1>
<FileUploader setFunction={setApartmentData} />
)
}
House.ts
type HouseType = {
owner: string;
pictures: string[];
}
function House () {
const [ houseData, setHouseData ] = useState<HouseType>({
owner: 'Jhon',
pictures: [ 'url1', 'url2' ]
})
return (
<h1>House</h1>
<FileUploader setFunction={setHouseData} />
)
}
As you can see I'm adding a FileUploader
component which will update the pictures
array of its parent using the set function that comes with the useState
hook:
type FileUploaderProps = {
setFunction: React.Dispatch<React.SetStateAction<HouseType> | React.SetStateAction<ApartmentType>>
}
function FileUploader ({ setFunction }: FileUploaderProps) {
function updatePictures () {
setFunction((prevValue: any) => ({ ...prevValue, pictures: [ ...prevValue.pictures, 'newUrl1', 'newUrl2'] }))
}
return (
<div>
<h1>File Uploader</h1>
<button type='button' onClick={updatePictures}></button>
</div>
)
}
But here is where the issue appears, in Apartment
and House
for the setFunction
prop in FileUploader
TS is giving me this error:
Type 'Dispatch<SetStateAction<HouseType>>' is not assignable to type 'Dispatch<SetStateAction<ApartmentType> | SetStateAction<HouseType>>'.
Type 'SetStateAction<ApartmentType> | SetStateAction<HouseType>' is not assignable to type 'SetStateAction<HouseType>'.
Type 'ApartmentType' is not assignable to type 'SetStateAction<HouseType>'.
Property 'owner' is missing in type 'ApartmentType' but required in type 'HouseType'
What I'm doing wrong?, I though that typing the setFunction
prop in FileUploader
as:
React.Dispatch<React.SetStateAction<HouseType> | React.SetStateAction<ApartmentType>>
would be sufficient to account for the two possibilities but it is not.
Here is a link for a playground
CodePudding user response:
You are making some confusion with the template types and Union type in "wrong" place (React.SetStateAction<Apartment>
and React.SetStateAction<House>
). It would be best if you made the function a Union type such as:
type FileUploaderProps = {
setFunction: React.Dispatch<React.SetStateAction<House>> | React.Dispatch<React.SetStateAction<Apartment>>
}