diff --git a/src/types.ts b/src/types.ts index 7ac29ab..854196f 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 | 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 diff --git a/tests/fromPartial.test.ts b/tests/fromPartial.test.ts index 08cb951..a228b80 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<{ @@ -89,4 +93,17 @@ describe("fromPartial", () => { }), ); }); + + it("Should handle deeply recursive partial types", () => { + interface RecursiveInterface { + (bar: string) : RecursiveInterface; + foo: { + deepProperty: string + }, + } + accept( + fromPartial(bar => (bar2)=> ({})), + ); + }); + });