I have a Test
component that must accept a one
prop where the object must have an a
field but only have an id
field if the two
prop is not provided. If the two
prop is provided then the one
prop's object must not have an id
field.
How can this be achieved? The closest I could get is using this interface:
interface Test {
one: {
a: string;
id?: number;
};
two?: number;
}
Obviously it will not work properly since the id
field and two
props are just set to optional rather than conditioning from each other.
Here is the demo I have built:
export default function App() {
return (
<div>
<Test
one={{
a: 'valid example with id and no two prop',
id: 5,
}}
/>
<Test
one={{
a: 'valid example with two prop and no id field',
}}
two={9}
/>
<Test
one={{
a: 'should have id or two prop; needs to error',
}}
/>
<Test
one={{
a: 'cannot have both id field AND two prop; needs to error',
id: 2,
}}
two={5}
/>
</div>
);
}
interface Test {
one: {
a: string;
id?: number;
};
two?: number;
}
const Test = ({ one, two }: Test): JSX.Element => {
return <p>test</p>;
};
Stackblitz demo: https://stackblitz.com/edit/react-ts-2wsnwj?file=App.tsx
I wondered whether I could write the types like this, but apparently not:
type One = {
a: string
id?: number
}
type Two = One.id ? number : null
Any advice would be appreciated, thank you
CodePudding user response:
make Test
a union type which covers all acceptable states:
type Test = {one: {a: string; id: number}} |
{one: {a:string}; two:number}