-
-
Notifications
You must be signed in to change notification settings - Fork 654
pick-deep: Fix the case when the key or element is an union type (#1224)
#1241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@taiyakihitotsu Thanks for the PR! I’m a bit occupied with festivities, I’ll try to review it sometime next week. |
|
I've added a fix commit for #1223. @sindresorhus @som-sm |
|
I found a bug in this case and will fix it as well. type unionKeyUnionObject_Actual = PickDeep<{obj: {a: string; b: number; c: boolean} | {d: 0}}, `obj.${'b' | 'c' | 'd'}`>; // {obj: {b: number; d: 0; c: boolean}} |
|
And type-fest/source/union-to-tuple.d.ts Line 13 in ee29ef7
I'll move it to internal if ok to combine them into one PR. |
|
I’ve got an idea for the fix, but not sure when I can get back to it, so I leave this as a draft for now. |
|
I fixed the issues (#1224, #1223) and a bug in the comment I posted earlier. diffI defined a converter that transforms template literals like (When the implementation of Path relies on Union type distribution, the original structure can be lost. For example, in an extreme case like I've also defined some internal helper functions for certain getter functions, which ignore the distinction between
IsNever bugOutdated. see this move to internalIt seems reasonable to mark some of the functions as internal. |
Is there a simpler reproduction of where |
|
This comment is outdated, see this new comment It may only fail when using recursion with Current
|
|
type LastOfUnion<T> =
UnionToIntersection<
T extends infer A
? () => A
: never> extends () => (infer R)
? R extends T ? R : never
: never;
This works well only in the test cases above, but it cannot replace the existing code. |
type LastOfUnion<T> =
UnionToIntersection<
T extends infer A
? () => A
: never> extends () => (infer R)
? R
: never;
type a = LastOfUnion<never>; // unknownOK I see that this returns The current (at 590efae8223ed1ac61855840dff114360b7c6807) definition of type test = LastOfUnion<Exclude<string, string>> extends infer U ? PreviousIsNever<U> : 'false';
// ^ false
export type PreviousIsNever<T> = [T] extends [never] ? true : false;Apologies for my misunderstanding. In any case, Should I include it in this PR? Or not? |
In this PR, yes. |
|
Thanks for your response! I wrote a comment and provided two examples of how to use it for recursion. And I made a small change to The latest status of this PR
|
This PR fixes #1224.
(I’m opening this because I previously sent a message about the issue, but it seems that no one has started working on it.)
Approach
The issue can be broken down into two separate bugs:
PickDeepfails to pick values when the object’s properties are of a union type. (2025/09/29 ... ok)PickDeepdoesn't properly merge results when the path is a union type.(2025/09/29 ... it has a bug)(2025/10/01 ... ok)The first was fixed by applying distribution over the union type in the object.
For the second issue, the fix involves evaluating each path in the union individually, obtaining the result as a union of objects, and then merging them using(2025/10/01 ... See)MergeNarrow.related issue
I'm not sure whether the expected value shown in #1223 is truly correct according to the
PickDeepspecification, so I’ve decided to leave that issue for now.(In the current commit, the result for that case would be(2025/10/01 ... See){arr: []}. I think this is caused byMergeNarrow.)If I should include a fix for #1223 in this PR as well, please let me know.
note
I rewrote the tests to be more strict, using the following pattern:
This is because some previous tests using
expectType<T>(value)were passing unintentionally.