Two parent components are sharing the same child components, but have differen properties passed.
Since ParentB
doesn't pass the name
props, it throws the error
type '{ mail: any; }' is missing the following properties from type '{ mail: string; name: string; } name
See the example:
const ParentA=()=>{
return (
<>
<Child
mail={project.mail}
name={name}
/>
</>
)
}
const ParentB=()=>{
return (
<>
<Child
mail={project.mail}
/>
</>
)
}
const Child: FunctionComponent<{
mail: string;
name: string;
}> = ({ mail, name }) => {
}
I tried to solve it this way in Child
component, but it throws another error in jsx
interface ChildProps {
mail: string;
name: boolean;
}
interface CHildWitouthNameProps {
mail: string;
name?: never;
}
type Props = ChildProps | CHildWitouthNameProps;
const Child = (props: Props) => {
Another try was
const Child: FunctionComponent<{
mail: string;
name?: boolean;
}> = ({ mail, name }) => {
}
But it throws another error in jsx
name is possibly 'undefined'
return (
<div>
{name}
</div>
)
How to fix the error?
Any Help will be appreciated.
CodePudding user response:
Just add ? which means that that is an optional key.
const ParentA=()=>{
return (
<>
<Child
mail={project.mail}
loading={loading}
/>
</>
)
}
const ParentB=()=>{
return (
<>
<Child
mail={project.mail}
/>
</>
)
}
const Child: FunctionComponent<{
mail: string;
loading?: boolean;
}> = ({ mail, loadedData }) => {
}
CodePudding user response:
Your last approach
const Child: FunctionComponent<{
mail: string;
name?: boolean;
}> = ({ mail, name }) => {
}
seems correct, since logically the child component must have a mail
prop, but it doesn't necessarily need to have a name
prop. Based on this definition, the second error you describe,
name is possibly 'undefined'
seems like TypeScript functioning as intended. It's telling you that there is a prop which might not be defined, being used in a way that would break the application if it actually was undefined. The way to fix this is by ensuring that wherever you use the name
prop in a way that's sensitive to whether or not it's defined, you should include good checks. There are a couple ways to do this:
return (
<div>
{name || "No name given"}
</div>
)
^this way fills in the name with the placeholder whenever it's not present,
return (
{name && <div>
{name}
</div>}
)
^this way only renders the whole div if name
is defined to begin with.
Again, it seems like it depends on what you're going for, but this might be some good things to try first.