In react I’m trying to set a conditional type in a function argument depending if a prop is pass in the component.
Here is the example, I have this component:
const DatePicker = ({
handleDateChange,
value,
objectKey,
}: {
handleDateChange: (value: Dayjs | { [x: string]: Dayjs }) => void;
value: Dayjs;
objectKey?: string;
}) => JSX
What I want to do is that, if "objectKey" is pass as props than the type of the paremeter "value" in the function handleDateChange would be { [x: string]: Dayjs }, otherwise it would be value: Dayjs.
Does anyone have an idea of how to make this?
2
Answers
You can achieve something like this with function overloads.
With this approach
DatePicker
can only be called according to your definition, however the implementation won’t know the correlation betweenhandleDateChange
andobjectKey
so you still need to handle that explicitly.Without knowing any details of
DatePicker
I think it would be better to only use one signature and let the parent component make changes to fitDatePicker
instead of havingDatePicker
handle special cases from it’s parents.The following type should do what you are interested in, using Unions and Intersections:
Explanation:
value
is always part of the type, we add it first to get it out of the way, and so that we don’t duplicate it.&
) that part with the union (|
) of the two situations that can vary according to your rules, specifically:handleDateChange
varies based on whether the type ofobjectKey
isstring
orundefined
(not set).objectKey
differently (first with?
, then without) because we want to let TypeScript know it is completely omittable when not set.You can simply assign it to the props parameter object: