Reputation: 252
I'm struggling to understand how to validate that two props either exist or don't.
In other words, they are both optional, but if one exists, the other must also.
I don't quite understand how a conditional type would work in this scenario, in all the examples I've seen the condition is if the class extends another class or not, so how would that work here?
interface DateInputProps {
onDateChange: (date: Date) => void;
date: any;
}
interface DateInputPropsNull {}
type SelectiveProps<T> = T extends _what?_
? DateInputPropsNull
: DateInputProps;
class DateInput extends React.Component<
SelectiveProps<_what?_>,
DateInputState
> {
render() {
const {
date = this.state.date,
onDateChange = (date: any) => this.setState({ date })
} = this.props;
...
}
}
I would then expect to be able to do:
<DateInput /> //No type error
<DateInput date="2011-01-05" onDateChange={(date)=> console.log(date)}/> //No type error
<DateInput date="2011-01-05" /> //Error - onDateChange is required
Upvotes: 3
Views: 1767
Reputation: 2595
You can do something like this
interface DateInputProps {
onDateChange: (date: Date) => void;
date: string;
}
interface DateInputPropsNull {
onDateChange?: undefined,
date?: undefined
}
type SelectiveProps = DateInputProps | DateInputPropsNull
class DateInput extends React.Component<SelectiveProps>
So if you pass one of the value you will get the type error. The only problem with this solution is that when you pass undefined
to date
or onDateChange
, it will not give you the error.
<DateInput /> //No type error
<DateInput date="2011-01-05" onDateChange={(date)=> console.log(date)}/> //No type error
<DateInput date="2011-01-05" /> //Error - onDateChange is required
<DateInput date={undefined} onDateChange={undefined} /> // No type error
Upvotes: 5
Reputation: 5967
I suppose you can do it like this:
interface IDateInputProps {
date?: any;
onDateChange()?: void;
}
export class DateInput extends React.Component<IDateInputProps, DateInputState> {
render() {
const { date, onDateChange } = this.props;
if ((!date && onDateChange) || (date && !onDateChange)) {
throw new Error('"date" and "onDateChange" props must occur together");
}
...
}
}
I haven't tested it, but I think that would do what you want.
Upvotes: 0