Home > Net >  Why does the property of an object used in the union has the type any?
Why does the property of an object used in the union has the type any?

Time:12-17

I have a component that has 3 props: toValue, fromValue, children. The first 2 of them are optional, but if one of them is specified, then the other must also be specified. The children prop is a function that has the inputProps argument, which should be equal to either the return type of toValue function (TInputValue), if specified, or TStateValue.

I wrote the following code, but I didn't understand why inputProps is any in cases where the toValue function is specified. How to fix it?

interface IP<T> {
  value: T
  onChange: (value: T) => void
}
interface A<TStateValue> {
  toValue?: never
  fromValue?: never
  children: (inputProps: IP<TStateValue>) => null
}
interface B<TStateValue, TInputValue>  {
  toValue: (value: TStateValue) => TInputValue
  fromValue: (value: TInputValue) => TStateValue
  children: (inputProps: IP<TInputValue>) => null
}
type C<TStateValue, TInputValue> =
  | A<TStateValue>
  | B<TStateValue, TInputValue>

const propsWithoutToValue: C<number, string> = {
  children: (inputProps) => null, // `inputProps` is `IP<number>`. Nice!
}
const propsWithToValue: C<number, string> = {
  toValue: (value) => value.toString(), // The return type is a `string`, so the `inputProps` must be `IP<string>`
  fromValue: (value) => Number(value),
  children: (inputProps) => null, // `inputProps` is any, but must be `IP<string>`. How to fix it?
}

I have created a repo with my problem that I'm trying to solve: enter image description here

enter image description here

point B: the reason typescript think you try to union 2 functions is because union function with the same object properties behave in the same way as union of both functions

enter image description here

this basically mean {b:((a:1)=>void)} | {b:((a:number)=>void)} is literally {b:((a:1)=>void) | ((a:number)=>void)}

there are few things that I cant explain:

  1. the justification behind behavior shown in point A and B (what is the purpose)
  2. it seem like discriminated union (or union in general) not working properly with function type
  3. point A does not apply to propsWithoutToValue but apply to propsWithToValue, most likely is the after wave of point 2
  • Related