form icon indicating copy to clipboard operation
form copied to clipboard

fix(core): add support to union types for `DeepValue`

Open irwinarruda opened this issue 1 year ago • 5 comments

Solves #691

Explanation

@Balastrong provided two issues in the example. Only one of those is a bug. Consider the following code:

type Text = { answer: string; textAnswer: string }
type Number = { answer: number }
type FormType = { questions: Array<Text | Number> }
  • When calling DeepValue<FormType, 'questions[0].textAnswer'> the result is unknown. This is a bug!
  • When calling DeepValue<FormType, 'questions[0].answer'> the result is number | string. This is not a bug because Typescript will never know the current state of the if checks.

Solution

As I explained on the issue page, the problem was solved by swapping the default typescript get function with a custom one.

Problems found along the way

Recently, the #713 and #717 were merged. From what I gathered, if there is a nullable union, all the properties from the object part will also be nullable. So for example:

type Obj = { a: { b: string } | null }
// DeepValue<Obj, 'a.b'> -> string | null

In order to create a standardized behavior, I decided to ask you some questions.

  • Why is it only null values? What about optional and undefined?
  • Shouldn't it work with deep nested values?
DeepValue<{ a: { b: { c: string } } | null }, 'a.b.c'>
// should be -> string | null but is only string
  • Should the object union work the same way? So for the first example I gave:
DeepValue<FormType, 'questions[0].textAnswer'>
// should be -> string | undefined instead of just string (which is the way I implemented it)

Please let me know if you would like to chat more about it. I recently joined the Tanstack Discord.

irwinarruda avatar May 30 '24 04:05 irwinarruda