Skip to content

ConditionalPickDeep / SimplifyDeep: Prevent mapping over built-ins#1293

Merged
sindresorhus merged 6 commits intosindresorhus:mainfrom
ryangoree:main
Nov 10, 2025
Merged

ConditionalPickDeep / SimplifyDeep: Prevent mapping over built-ins#1293
sindresorhus merged 6 commits intosindresorhus:mainfrom
ryangoree:main

Conversation

@ryangoree
Copy link
Contributor

@ryangoree ryangoree commented Nov 7, 2025

IsPlainObject currently returns true for Promise, WeakMap, and WeakSet types, and returns never for never. This affects types like ConditionalPickDeep that rely on it for deciding when to map over a type's fields.

This PR fixes the behavior by ensuring IsPlainObject returns false for these types.

type Example = {
	a: string;
	b: Promise<string>;
	c: WeakMap<WeakKey, string>;
	d: WeakSet<WeakKey>;
};

type Current = ConditionalPickDeep<Example, string>;
//=> {
//   a: string;
//   b: {
//     readonly [Symbol.toStringTag]: string;
//   };
//   c: {
//     readonly [Symbol.toStringTag]: string;
//   };
//   d: {
//     readonly [Symbol.toStringTag]: string;
//   };
// };

type Fixed = ConditionalPickDeep<Example, string>;
//=> {a: string;}

never example:

type Example = {
	a: string;
	b: never;
};

type Current = ConditionalPickDeep<Example, string, {condition: 'equality'}>;
//=> {a: string; b: never}

type Fixed = ConditionalPickDeep<Example, string, {condition: 'equality'}>;
//=> {a: string;}

This PR also fixes the SimplifyDeep type:

type Example = {
	a: string;
} & {
	b: Promise<string>;
	c: ReadonlySet<string>;
	d: WeakSet<WeakKey>;
	e: ReadonlyMap<string, string>;
	f: WeakMap<WeakKey, string>;
};

type Current = SimplifyDeep<Example>;
//=> {
//   a: string;
//   b: {
//     ...;
//   };
//   c: {
//     ...;
//   };
//   d: {
//     ...;
//   };
//   e: {
//     ...;
//   };
//   f: {
//     ...;
//   };
// };

type Fixed = SimplifyDeep<Example>;
//=> {
//   a: string;
//   b: Promise<string>;
//   c: ReadonlySet<string>;
//   d: WeakSet<WeakKey>;
//   e: ReadonlyMap<string, string>;
//   f: WeakMap<WeakKey, string>;
// };

@ryangoree ryangoree changed the title ConditionalPickDeep: Fix behavior with Promise, WeakMap, and WeakSet ConditionalPickDeep: Fix behavior with Promise, WeakMap, WeakSet, never Nov 7, 2025
@ryangoree ryangoree changed the title ConditionalPickDeep: Fix behavior with Promise, WeakMap, WeakSet, never ConditionalPickDeep / SimplifyDeep: Prevent mapping over built-ins Nov 8, 2025
Copy link
Collaborator

@som-sm som-sm left a comment

Choose a reason for hiding this comment

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

LGTM!

@sindresorhus sindresorhus merged commit f14a75a into sindresorhus:main Nov 10, 2025
8 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.

3 participants