Home > Back-end >  How to base Typescript types off of the value of other props?
How to base Typescript types off of the value of other props?

Time:10-20

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
}

Playground

  • Related