Skip to content

PartialDeep: Fix behaviour with functions containing multiple call signatures#1259

Merged
sindresorhus merged 3 commits intomainfrom
fix/partial-deep-with-multiple-call-signatures
Oct 2, 2025
Merged

PartialDeep: Fix behaviour with functions containing multiple call signatures#1259
sindresorhus merged 3 commits intomainfrom
fix/partial-deep-with-multiple-call-signatures

Conversation

@som-sm
Copy link
Collaborator

@som-sm som-sm commented Oct 1, 2025

This PR adds handling of multiple call signatures in PartialDeep, similar to RequiredDeep.

Currently, if PartialDeep is instantiated with a function containing multiple call signatures and a property, the call signatures are not preserved in the resultant type. This PR fixes this by simply bypassing such inputs, similar to how it's done in RequiredDeep.

Current behaviour:

type FunctionWithProperties = {(a1: number): string; (a1: string, a2: number): number; p1: string};
declare const functionWithProperties: PartialDeep<FunctionWithProperties>;

const r1 = functionWithProperties(1); // Errors
const r2 = functionWithProperties('a', 1);
//    ^? const r2: number

type JustProperties = Simplify<typeof functionWithProperties>; // `p1` is correctly optional
//   ^? type JustProperties = { p1?: string; }

Fixed behaviour:

type FunctionWithProperties = {(a1: number): string; (a1: string, a2: number): number; p1: string};
declare const functionWithProperties: PartialDeep<FunctionWithProperties>;

const r1 = functionWithProperties(1);
//    ^? const r1: string
const r2 = functionWithProperties('a', 1);
//    ^? const r2: number

type JustProperties = Simplify<typeof functionWithProperties>; // `p1` is NO longer optional, this is a limitation
//   ^? type JustProperties = { p1: string; }

expectType<{p1: string}>({} as Simplify<typeof functionWithProperties4>);
expectType<string>(functionWithProperties4(1));
expectType<number>(functionWithProperties4('foo', 1));
expectNotType<{p1: string}>({} as Simplify<typeof functionWithProperties4>);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed @ts-expect-error because that's not reliable, not all "tsd" errors surface as TypeScript errors.

? Promise<RequiredDeep<ValueType>>
: T extends (...arguments_: any[]) => unknown
? {} extends RequiredObjectDeep<T>
? IsNever<keyof T> extends true
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is better than {} extends RequiredObjectDeep<T> because {} extends things like {a?: string}, so in PartialDeep we couldn't have used this approach.

@som-sm som-sm requested review from Copilot and sindresorhus October 1, 2025 10:35
@som-sm som-sm marked this pull request as ready for review October 1, 2025 10:35
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes a bug in the PartialDeep utility type where functions with multiple call signatures were not properly handled, causing the call signatures to be lost while making properties optional. The fix aligns the behavior with RequiredDeep by bypassing such inputs to preserve function call signatures.

  • Updated PartialDeep to handle functions with multiple call signatures correctly
  • Added comprehensive test coverage for the new behavior
  • Aligned the implementation approach with existing RequiredDeep behavior

Reviewed Changes

Copilot reviewed 2 out of 4 changed files in this pull request and generated 1 comment.

File Description
test-d/partial-deep.ts Adds tests for functions with multiple call signatures to verify call signatures are preserved
test-d/required-deep.ts Updates existing tests to verify call signatures are preserved and uses expectNotType for properties

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@som-sm som-sm force-pushed the fix/partial-deep-with-multiple-call-signatures branch from 4aae28e to 1c7cb65 Compare October 1, 2025 10:37
@sindresorhus sindresorhus merged commit 3bd9de6 into main Oct 2, 2025
6 checks passed
@sindresorhus sindresorhus deleted the fix/partial-deep-with-multiple-call-signatures branch October 2, 2025 03:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants