Skip to content

Commit

Permalink
PartialDeep: Ensure it doesn't recurse into prototype properties (#738
Browse files Browse the repository at this point in the history
)
  • Loading branch information
Emiyaaaaa committed Nov 2, 2023
1 parent 9960ba4 commit 5eeac02
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 5 deletions.
10 changes: 5 additions & 5 deletions source/partial-deep.d.ts
@@ -1,4 +1,4 @@
import type {BuiltIns} from './internal';
import type {BuiltIns, UnknownRecord} from './internal';

/**
@see PartialDeep
Expand Down Expand Up @@ -69,17 +69,17 @@ export type PartialDeep<T, Options extends PartialDeepOptions = {}> = T extends
? PartialReadonlyMapDeep<KeyType, ValueType, Options>
: T extends ReadonlySet<infer ItemType>
? PartialReadonlySetDeep<ItemType, Options>
: T extends object
? T extends ReadonlyArray<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156
: T extends UnknownRecord
? PartialObjectDeep<T, Options>
: T extends ReadonlyArray<infer ItemType> // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156
? Options['recurseIntoArrays'] extends true
? ItemType[] extends T // Test for arrays (non-tuples) specifically
? readonly ItemType[] extends T // Differentiate readonly and mutable arrays
? ReadonlyArray<PartialDeep<ItemType | undefined, Options>>
: Array<PartialDeep<ItemType | undefined, Options>>
: PartialObjectDeep<T, Options> // Tuples behave properly
: T // If they don't opt into array testing, just use the original type
: PartialObjectDeep<T, Options>
: unknown;
: T;

/**
Same as `PartialDeep`, but accepts only `Map`s and as inputs. Internal helper for `PartialDeep`.
Expand Down
3 changes: 3 additions & 0 deletions test-d/partial-deep.ts
Expand Up @@ -10,6 +10,7 @@ const foo = {
bar: {
function: (_: string): void => undefined,
classConstructor: ClassA,
html: document.createElement('div'),
object: {key: 'value'},
string: 'waldo',
number: 1,
Expand Down Expand Up @@ -58,6 +59,8 @@ expectAssignable<ReadonlyMap<string | undefined, string | undefined> | undefined
expectAssignable<ReadonlySet<string | undefined> | undefined>(partialDeepFoo.bar!.readonlySet);
expectType<ReadonlyArray<string | undefined> | undefined>(partialDeepFoo.bar!.readonlyArray);
expectType<readonly ['foo'?] | undefined>(partialDeepFoo.bar!.readonlyTuple);
// Test for https://github.com/sindresorhus/type-fest/issues/651
expectType<HTMLDivElement | undefined>(partialDeepFoo.bar!.html);
// Check for compiling with omitting partial keys
partialDeepFoo = {baz: 'fred'};
partialDeepFoo = {bar: {string: 'waldo'}};
Expand Down

0 comments on commit 5eeac02

Please sign in to comment.