From 170ce52ac15d796ae3a192166d9484d60d9f2ab5 Mon Sep 17 00:00:00 2001 From: "marcin.piniarski" Date: Wed, 8 Mar 2023 14:27:52 +0100 Subject: [PATCH] fix: DeepPartial with generic parameter should allow assigning {} --- src/__snapshots__/mapped-types.spec.ts.snap | 12 ++++++++---- src/mapped-types.spec.snap.ts | 18 +++++++++++++----- src/mapped-types.spec.ts | 10 +++++++++- src/mapped-types.ts | 11 ++++++----- 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/__snapshots__/mapped-types.spec.ts.snap b/src/__snapshots__/mapped-types.spec.ts.snap index b8e2e49..c96b64e 100644 --- a/src/__snapshots__/mapped-types.spec.ts.snap +++ b/src/__snapshots__/mapped-types.spec.ts.snap @@ -39,6 +39,10 @@ exports[`DeepNonNullable testType['first']['second' exports[`DeepNonNullable testType['first']['second']['name']>() (type) should match snapshot 1`] = `"string"`; +exports[`DeepPartial testType>({}) (type) should match snapshot 1`] = `"DeepPartial<{ first: { second: { name: string; }; }; }>"`; + +exports[`DeepPartial testType>({}) (type) should match snapshot 1`] = `"DeepPartial"`; + exports[`DeepPartial testType>>() (type) should match snapshot 1`] = `"string"`; exports[`DeepPartial testType() (type) should match snapshot 1`] = `"string | undefined"`; @@ -49,13 +53,13 @@ exports[`DeepPartial testType() (type) should match snapsho exports[`DeepPartial testType() (type) should match snapshot 1`] = `"string | undefined"`; -exports[`DeepPartial testType() (type) should match snapshot 1`] = `"_DeepPartialObject<{ second: { name: string; }[]; }> | undefined"`; +exports[`DeepPartial testType() (type) should match snapshot 1`] = `"DeepPartial<{ second: { name: string; }[]; }> | undefined"`; -exports[`DeepPartial testType() (type) should match snapshot 1`] = `"_DeepPartialObject<{ second: (value: number) => string; }> | undefined"`; +exports[`DeepPartial testType() (type) should match snapshot 1`] = `"DeepPartial<{ second: (value: number) => string; }> | undefined"`; -exports[`DeepPartial testType() (type) should match snapshot 1`] = `"_DeepPartialObject<{ second: { name: string; }; }> | undefined"`; +exports[`DeepPartial testType() (type) should match snapshot 1`] = `"DeepPartial<{ second: { name: string; }; }> | undefined"`; -exports[`DeepPartial testType() (type) should match snapshot 1`] = `"_DeepPartialObject<{ name: string; }> | undefined"`; +exports[`DeepPartial testType() (type) should match snapshot 1`] = `"DeepPartial<{ name: string; }> | undefined"`; exports[`DeepReadonly testType>>() (type) should match snapshot 1`] = `"_DeepReadonlyObject<{ first: { second: { name: string; }[]; }; }>"`; diff --git a/src/mapped-types.spec.snap.ts b/src/mapped-types.spec.snap.ts index a4397ac..9353853 100644 --- a/src/mapped-types.spec.snap.ts +++ b/src/mapped-types.spec.snap.ts @@ -30,7 +30,7 @@ import { _DeepReadonlyObject, _DeepRequiredArray, _DeepRequiredObject, - _DeepPartialObject, + _DeepPartial, _DeepPartialArray, RequiredKeys, OptionalKeys, @@ -444,11 +444,11 @@ type RequiredOptionalProps = { }; }; const partialNested: DeepPartial = {} as any; - // @dts-jest:pass:snap -> _DeepPartialObject<{ second: { name: string; }; }> | undefined + // @dts-jest:pass:snap -> DeepPartial<{ second: { name: string; }; }> | undefined testType(); const second = partialNested.first!.second; - // @dts-jest:pass:snap -> _DeepPartialObject<{ name: string; }> | undefined + // @dts-jest:pass:snap -> DeepPartial<{ name: string; }> | undefined testType(); const name = second!.name; @@ -462,7 +462,7 @@ type RequiredOptionalProps = { }; const nestedArrayPartial: DeepPartial = {}; - // @dts-jest:pass:snap -> _DeepPartialObject<{ second: { name: string; }[]; }> | undefined + // @dts-jest:pass:snap -> DeepPartial<{ second: { name: string; }[]; }> | undefined testType(); const arrayProp = nestedArrayPartial.first!.second; @@ -479,7 +479,7 @@ type RequiredOptionalProps = { }; }; const nestedFunctionPartial: DeepPartial = {}; - // @dts-jest:pass:snap -> _DeepPartialObject<{ second: (value: number) => string; }> | undefined + // @dts-jest:pass:snap -> DeepPartial<{ second: (value: number) => string; }> | undefined testType(); const functionProp = nestedFunctionPartial.first!.second; @@ -487,6 +487,14 @@ type RequiredOptionalProps = { testType(); // @dts-jest:pass:snap -> string testType>>(); + + // @dts-jest:pass:snap -> DeepPartial<{ first: { second: { name: string; }; }; }> + testType>({}); + + () => { + // @dts-jest:pass:snap -> DeepPartial + testType>({}); + }; } // @dts-jest:group Brand diff --git a/src/mapped-types.spec.ts b/src/mapped-types.spec.ts index a6de52c..8df8c4e 100644 --- a/src/mapped-types.spec.ts +++ b/src/mapped-types.spec.ts @@ -30,7 +30,7 @@ import { _DeepReadonlyObject, _DeepRequiredArray, _DeepRequiredObject, - _DeepPartialObject, + _DeepPartial, _DeepPartialArray, RequiredKeys, OptionalKeys, @@ -487,6 +487,14 @@ type RequiredOptionalProps = { testType(); // @dts-jest:pass:snap testType>>(); + + // @dts-jest:pass:snap + testType>({}); + + () => { + // @dts-jest:pass:snap + testType>({}); + }; } // @dts-jest:group Brand diff --git a/src/mapped-types.ts b/src/mapped-types.ts index 54395d9..f0027c8 100644 --- a/src/mapped-types.ts +++ b/src/mapped-types.ts @@ -501,18 +501,19 @@ export type _DeepNonNullableObject = { * }; * type PartialNestedProps = DeepPartial; */ -export type DeepPartial = T extends Function +export type DeepPartial = { [P in keyof T]?: _DeepPartial }; + +/** @private */ +export type _DeepPartial = T extends Function ? T : T extends Array ? _DeepPartialArray : T extends object - ? _DeepPartialObject + ? DeepPartial : T | undefined; /** @private */ // tslint:disable-next-line:class-name -export interface _DeepPartialArray extends Array> {} -/** @private */ -export type _DeepPartialObject = { [P in keyof T]?: DeepPartial }; +export interface _DeepPartialArray extends Array<_DeepPartial> {} /** * Brand