From 75edeefd4a52c528b2c132964734fd68cdc645d3 Mon Sep 17 00:00:00 2001 From: Haozheng Li Date: Wed, 25 Oct 2023 17:27:39 +0800 Subject: [PATCH] `PartialDeep`: Skip constructor (#730) --- source/partial-deep.d.ts | 26 ++++++++++++-------------- test-d/partial-deep.ts | 10 ++++++++++ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/source/partial-deep.d.ts b/source/partial-deep.d.ts index 14eb2d49..b2299be6 100644 --- a/source/partial-deep.d.ts +++ b/source/partial-deep.d.ts @@ -59,7 +59,7 @@ const partialSettings: PartialDeep = { @category Set @category Map */ -export type PartialDeep = T extends BuiltIns +export type PartialDeep = T extends BuiltIns | (((...arguments_: any[]) => unknown)) | (new (...arguments_: any[]) => unknown) ? T : T extends Map ? PartialMapDeep @@ -69,19 +69,17 @@ export type PartialDeep = T extends ? PartialReadonlyMapDeep : T extends ReadonlySet ? PartialReadonlySetDeep - : T extends ((...arguments_: any[]) => unknown) - ? T | undefined - : T extends object - ? T extends ReadonlyArray // 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> - : Array> - : PartialObjectDeep // Tuples behave properly - : T // If they don't opt into array testing, just use the original type - : PartialObjectDeep - : unknown; + : T extends object + ? T extends ReadonlyArray // 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> + : Array> + : PartialObjectDeep // Tuples behave properly + : T // If they don't opt into array testing, just use the original type + : PartialObjectDeep + : unknown; /** Same as `PartialDeep`, but accepts only `Map`s and as inputs. Internal helper for `PartialDeep`. diff --git a/test-d/partial-deep.ts b/test-d/partial-deep.ts index 93019446..2560d85e 100644 --- a/test-d/partial-deep.ts +++ b/test-d/partial-deep.ts @@ -1,10 +1,15 @@ import {expectType, expectError, expectAssignable} from 'tsd'; import type {PartialDeep} from '../index'; +class ClassA { + foo = 1; +} + const foo = { baz: 'fred', bar: { function: (_: string): void => undefined, + classConstructor: ClassA, object: {key: 'value'}, string: 'waldo', number: 1, @@ -30,6 +35,11 @@ let partialDeepFoo: PartialDeep = foo; expectError(expectType>(partialDeepFoo)); const partialDeepBar: PartialDeep = foo.bar; expectType(partialDeepFoo.bar); +// Check for constructor +expectType(partialDeepFoo.bar!.classConstructor); +const instance = new partialDeepFoo.bar!.classConstructor!(); +instance.foo = 2; +const b = partialDeepFoo.bar!.constructor; expectType<((_: string) => void) | undefined>(partialDeepFoo.bar!.function); expectAssignable(partialDeepFoo.bar!.object); expectType(partialDeepFoo.bar!.string);