From 4b41ca828489b1edddfc4f20b9827a6e2fcf0a44 Mon Sep 17 00:00:00 2001 From: Li Date: Sat, 24 Jun 2023 00:37:16 -0400 Subject: [PATCH 1/7] Preserve parameter inference --- src/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types.ts b/src/types.ts index 7ac29ab..3d49165 100644 --- a/src/types.ts +++ b/src/types.ts @@ -3,8 +3,8 @@ export type NoInfer = [T][T extends any ? 0 : never]; /** * Adapted from type-fest's PartialDeep */ -export type PartialDeep = T extends (...args: any[]) => any - ? PartialDeepObject | undefined +export type PartialDeep = T extends (...args: infer P) => infer R + ? (((...args: P) => PartialDeep) & PartialDeepObject) | undefined : T extends object ? T extends ReadonlyArray // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156 ? ItemType[] extends T // Test for arrays (non-tuples) specifically From 79c4a05c18f7150ee50875160d797c4fb814354b Mon Sep 17 00:00:00 2001 From: Li Date: Sat, 24 Jun 2023 01:16:09 -0400 Subject: [PATCH 2/7] Fix corner case when you stub in an empty function --- src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index 3d49165..1cc57f5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,7 +4,7 @@ export type NoInfer = [T][T extends any ? 0 : never]; * Adapted from type-fest's PartialDeep */ export type PartialDeep = T extends (...args: infer P) => infer R - ? (((...args: P) => PartialDeep) & PartialDeepObject) | undefined + ? ((...args: P) => PartialDeep | void & PartialDeepObject) | undefined : T extends object ? T extends ReadonlyArray // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156 ? ItemType[] extends T // Test for arrays (non-tuples) specifically From cf525ad1717d7d6cac5d7244ed55190049f0880a Mon Sep 17 00:00:00 2001 From: Li Date: Sat, 24 Jun 2023 01:19:24 -0400 Subject: [PATCH 3/7] Parenthesis --- src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index 1cc57f5..89b6d49 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,7 +4,7 @@ export type NoInfer = [T][T extends any ? 0 : never]; * Adapted from type-fest's PartialDeep */ export type PartialDeep = T extends (...args: infer P) => infer R - ? ((...args: P) => PartialDeep | void & PartialDeepObject) | undefined + ? ((...args: P) => PartialDeep | void) & PartialDeepObject | undefined : T extends object ? T extends ReadonlyArray // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156 ? ItemType[] extends T // Test for arrays (non-tuples) specifically From 9917eda78313ec0f1023658b30ed50ffabf99df4 Mon Sep 17 00:00:00 2001 From: Li Date: Mon, 26 Jun 2023 11:05:13 -0400 Subject: [PATCH 4/7] Update types.ts to include non-union type as well --- src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index 89b6d49..854196f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,7 +4,7 @@ export type NoInfer = [T][T extends any ? 0 : never]; * Adapted from type-fest's PartialDeep */ export type PartialDeep = T extends (...args: infer P) => infer R - ? ((...args: P) => PartialDeep | void) & PartialDeepObject | undefined + ? ((...args: P) => PartialDeep | void) & PartialDeepObject | PartialDeepObject | undefined : T extends object ? T extends ReadonlyArray // Test for arrays/tuples, per https://github.com/microsoft/TypeScript/issues/35156 ? ItemType[] extends T // Test for arrays (non-tuples) specifically From 275db070cffa36b4b8d189849531b1b1b3abe253 Mon Sep 17 00:00:00 2001 From: Li Date: Mon, 26 Jun 2023 11:08:43 -0400 Subject: [PATCH 5/7] Update fromPartial.test.ts to include function inference test --- tests/fromPartial.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/fromPartial.test.ts b/tests/fromPartial.test.ts index 08cb951..96212f0 100644 --- a/tests/fromPartial.test.ts +++ b/tests/fromPartial.test.ts @@ -69,6 +69,10 @@ describe("fromPartial", () => { it("Should accept functions", () => { accept<() => void>(fromPartial({})); }); + + it("Should deeply infer types from functions", () => { + accept<(foo: string) => (bar: number) => {baz: string}>(fromPartial((foo) => (bar) => {})); + }); it("Should accept interfaces which combine object properties and a call signature", () => { accept<{ From fae53e9ee60e5e510b1e0276be76916cb4dd16c8 Mon Sep 17 00:00:00 2001 From: Li Date: Mon, 26 Jun 2023 11:16:35 -0400 Subject: [PATCH 6/7] Added recursion use case --- tests/fromPartial.test.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/fromPartial.test.ts b/tests/fromPartial.test.ts index 96212f0..560053a 100644 --- a/tests/fromPartial.test.ts +++ b/tests/fromPartial.test.ts @@ -93,4 +93,17 @@ describe("fromPartial", () => { }), ); }); + + it("Can handle deeply recursive partial types", () => { + interface RecursiveInterface { + (bar: string) : RecursiveInterface; + foo: { + deepProperty: string + }, + } + accept( + fromPartial(bar => (bar2)=> ({})), + ); + }); + }); From c08de2deb17c5810f0aa7e76854ed3a858eb228e Mon Sep 17 00:00:00 2001 From: Li Date: Mon, 26 Jun 2023 11:17:35 -0400 Subject: [PATCH 7/7] Style consistency --- tests/fromPartial.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fromPartial.test.ts b/tests/fromPartial.test.ts index 560053a..a228b80 100644 --- a/tests/fromPartial.test.ts +++ b/tests/fromPartial.test.ts @@ -94,7 +94,7 @@ describe("fromPartial", () => { ); }); - it("Can handle deeply recursive partial types", () => { + it("Should handle deeply recursive partial types", () => { interface RecursiveInterface { (bar: string) : RecursiveInterface; foo: {