You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Cannot infer types on arrays of union of objects #691
When accessing to questions[0].answer (field in both types) the type is string | number.
When accessing to questions[0].textAnswer (field on one type only) the type is unkown
Have a structure with an array of union of objects
Use field.state in jsx
Expected behavior
Not sure if it's a bug or a missing feature, but I'd like a way to know which is the correct type of the array entry and have all the fields typed accordingly.
The form is handling the values right, typescript isn't.
I found this problem interesting so I investigated a little. From what I've gathered, the issue revolves around the DeepValue type and happens because of a default typescript behavior with union types:
typeA={a: string;};typeB={b: number;};typeC=boolean;// Getting a value from a union causes some problems and the DeepValue uses this approachtyperesult1=(A|B)["a"];// anytyperesult2=(B|C)["b"];// any
My idea to solve it boils down to creating a new Get type that behaves differently from the default typescript one:
typeGet<T,Kextendsstring/* or keyof T*/>=Textends{[KeyinK]: infer V;} ? V : never;typeresult1=Get<A|B,"a">;// stringtyperesult2=Get<B|C,"b">;// number
Though I created it, I don't fully know how the Get type works because it sometimes behaves strangely, so this solution feels a bit hacky. Look at what I found changing the else clause. It might be a typescript bug.
typeGet<...>=Textends{ ... } ? V : unknown;typeresult1=Get<A|B,"a">;// unknowntyperesult2=Get<B|C,"b">;// unknowntypeGet<...>=Textends{ ... } ? V : undefined;typeresult1=Get<A|B,"a">;// string | undefinedtyperesult2=Get<B|C,"b">;// number | undefinedtypeGet<...>=Textends{ ... } ? V : never;typeresult1=Get<A|B,"a"|"b">;// never
@crutchcorn, if you and the team think it's a good idea to continue with this issue, I would like to create a PR to solve it. Please let me know if I should.
@irwinarruda please do open a PR! :) We have extensive type tests, so we'll need to make sure they all pass, but any help here would be greatly appreciated!
Activity
irwinarruda commentedon May 11, 2024
I found this problem interesting so I investigated a little. From what I've gathered, the issue revolves around the
DeepValuetype and happens because of a default typescript behavior with union types:My idea to solve it boils down to creating a new
Gettype that behaves differently from the default typescript one:Though I created it, I don't fully know how the
Gettype works because it sometimes behaves strangely, so this solution feels a bit hacky. Look at what I found changing theelseclause. It might be atypescriptbug.@crutchcorn, if you and the team think it's a good idea to continue with this issue, I would like to create a PR to solve it. Please let me know if I should.
crutchcorn commentedon May 28, 2024
@irwinarruda please do open a PR! :) We have extensive type tests, so we'll need to make sure they all pass, but any help here would be greatly appreciated!
crutchcorn commentedon Mar 1, 2025
Should be fixed now