Skip to content

ConditionalPickDeep: Fix returning {} instead of never when no keys match#1360

Merged
sindresorhus merged 3 commits intosindresorhus:mainfrom
derodero24:fix/conditional-pick-deep-empty-object
Feb 14, 2026
Merged

ConditionalPickDeep: Fix returning {} instead of never when no keys match#1360
sindresorhus merged 3 commits intosindresorhus:mainfrom
derodero24:fix/conditional-pick-deep-empty-object

Conversation

@derodero24
Copy link
Contributor

Fixes #1358

Summary

  • When no keys match the given Condition at any depth, ConditionalPickDeep previously returned {} (empty object type). This allowed any properties to be assigned without type errors.
  • Added a _NeverIfEmpty helper that checks if the result has no keys and returns never in that case. This is applied only at the top level to avoid interfering with the internal recursive EmptyObject exclusion logic.
  • Updated JSDoc twoslash comment and test cases accordingly.

Note

This is the deep variant of the same issue fixed in #1359 for ConditionalPick.

>;
>>;

type _NeverIfEmpty<Type> = [keyof Type] extends [never] ? never : Type;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect, because keyof Type would be never even for unions with no common properties. For example, ConditionalPickDeep<{a: string} | {b: string}>, string> should return {a: string} | {b: string}, but with this change it returns never.

Suggested change
type _NeverIfEmpty<Type> = [keyof Type] extends [never] ? never : Type;
type _NeverIfEmpty<Type> = Type extends EmptyObject ? never : Type;

The above is better because it lets Type distribute, and EmptyObject is preferable to keyof Type since EmptyObject is already used to achieve the same behavior in nested cases.

}, (typeof conditionalPickDeepSymbol | undefined) | EmptyObject>, never, UnknownRecord>;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, fixed. Also added a test for the union case with no common properties.

@sindresorhus sindresorhus merged commit 6af847a into sindresorhus:main Feb 14, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ConditionalPickDeep returns {} instead of never when no keys match

3 participants