Is it possible to change the typescript prop type based off the runtime value of another prop?
For example
type MyComponent = {
propA: boolean | string
propB: typeof propA boolean ? number : string
}
something like this where based off another prop I then determine what prop type propB should be. I guess I can't do this because of runtime.
What would be the solution to that? I don't want to open up both props to have multiple types
The only solution I've got so far is to have separate distinct props that I use for my two different component cases
To make it clear I've got a wrapper around <ReactSelect />
and I want to pass in different types for the onChange
function based off of if the isMulti
prop is true or not as the docs say that the values should be different.
==EDIT==
type SelectWithQueryPropsSingle<Variables, OnQueryData> = {
onQuery: (data: OnQueryData, value: Option) => Array<Option>
value: Option
} & SelectWithQueryConsistentProps<Variables>
type SelectWithQueryPropsMulti<Variables, OnQueryData> = {
onQuery: (data: OnQueryData, value: Array<Option>) => Array<Option>
value: Array<Option>
} & SelectWithQueryConsistentProps<Variables>
when I call this:
onQuery(data, value)
TS complains saying:
Argument of type 'Option | Option[]' is not assignable to parameter of type 'Option & Option[]'.
so in this instance why is the union failing to marry up value with the value argument?
export const SelectWrapper = <QueryType, Variables, OnQueryData>({
// quite a few other props here but not listing them out
onQuery,
}:
| SelectWithQueryPropsSingle<Variables, OnQueryData>
| SelectWithQueryPropsMulti<Variables, OnQueryData>)
type SelectWithQueryPropsSingle<Variables, OnQueryData> = {
onQuery: (data: OnQueryData, value: Option) => Array<Option>
value: Option
} & SelectWithQueryConsistentProps<Variables>
type SelectWithQueryPropsMulti<Variables, OnQueryData> = {
onQuery: (data: OnQueryData, value: Array<Option>) => Array<Option>
value: Array<Option>
} & SelectWithQueryConsistentProps<Variables>
CodePudding user response:
The correct approach would be to use a union.
type MyComponent = {
propA: boolean
propB: number
} | {
propA: string
probB: string
}