I have the following TypeScript interface:
interface SelectProps {
options: Option[];
value: string[];
onChange: (value: string[]) => void;
}
I want to add boolean called isMultiple
that will change the types of the other properties.
When isMultiple=true
value:string[]
onChange: (value: string[]) => void;
When isMultiple=false
value:string
onChange: (value: string) => void;
Is it possible to dynamically set the type of other properties based on the value of one property?
It's a bit late but I hope it helps others like it helped me.
Discriminated unions, also known as tagged unions or algebraic data types can be used to solve this problem.
interface MultipleSelectProps {
isMultiple: true;
options: string[];
value: string[];
onChange: (value: string[]) => void;
}
interface SingleSelectProps {
isMultiple: false;
options: string[];
value: string;
onChange: (value: string) => void;
}
type SelectProps = MultipleSelectProps | SingleSelectProps;
Usage example:
function Select(props: SelectProps) {
if (props.isMultiple) {
const { value, onChange } = props;
onChange(value);
} else if (props.isMultiple === false) {
const { value, onChange } = props;
onChange(value);
}
}
Note: When
isMultiple
isundefined
ornull
it is not possible to infer the specific type ofSelectProps
. In these cases is necessary to do a strict comparisonisMultiple === false
.
Source: https://blog.mariusschulz.com/2016/11/03/typescript-2-0-tagged-union-types