Skip to content

Fix completions for generic overloads with mixed function/object parameters#62763

Closed
PaulyBearCoding wants to merge 1 commit intomicrosoft:mainfrom
PaulyBearCoding:fix-62693-generic-overload-completions
Closed

Fix completions for generic overloads with mixed function/object parameters#62763
PaulyBearCoding wants to merge 1 commit intomicrosoft:mainfrom
PaulyBearCoding:fix-62693-generic-overload-completions

Conversation

@PaulyBearCoding
Copy link
Copy Markdown

Fixes #62693

Problem

When a generic function has overloads with mixed parameter types (function vs object literal), TypeScript shows incorrect completions for object literals. For example:

declare function task<T>(make: () => T): void
declare function task<T>(arg: {make: () => T}): void

task({
    // BUG: Shows bind, call, apply instead of "make"
})

The editor shows function properties (bind, call, apply) instead of the expected object property "make".

Root Cause

During completion, generic type inference is blocked (type parameters are unknown). When chooseOverload evaluates candidates, it:

  1. Attempts to resolve the function-type overload first
  2. Cannot infer T during completion context
  3. Falls back to treating the object literal as a function type
  4. Returns function properties instead of object properties

The issue occurs because overload selection doesn't account for the syntactic context (completing an object literal) when generic inference is unavailable.

Solution

The fix tracks which argument position is being completed and uses this information during overload resolution to prefer object-type overloads when completing object literals.

Changes

types.ts (line 6311):
Added completionArgumentIndex to NodeLinks to track which argument is being completed.

checker.ts (lines 32072-32076):
Store the argument index when inference is blocked during completion:

if (isInferencePartiallyBlocked) {
    links.completionArgumentIndex = argIndex;
}

checker.ts (lines 36728-36832):
Enhanced chooseOverload to:

  1. Detect when completing an object literal at argument position 0
  2. Skip overload candidates with function-type parameters
  3. Accept object-type overload candidates even if the literal is incomplete

This allows the type checker to select the correct overload based on syntactic context rather than relying solely on type inference.

Why This Works

The fix is surgical and only affects generic overload resolution during completion:

  • Targeted scope: Only triggers for object literals at argument 0 with blocked inference
  • Preserved behavior: Non-generic overloads and other arguments remain unchanged
  • Syntactic guidance: Uses the object literal syntax to disambiguate overloads when type inference is unavailable

The approach respects TypeScript's existing completion infrastructure while providing better overload selection for this specific edge case.

Testing

Added comprehensive test coverage in completionForGenericOverloadObjectLiteral.ts:

  • Generic function-first overload (the bug)
  • Generic object-first overload (control)
  • Non-generic overload (control)
  • Multiple type parameters with optional properties (rigorous)

All tests verify that object properties appear in completions and function properties (bind, call, apply) are correctly excluded.

Test results: 99,000 passing, 0 regressions

…meters

Fixes microsoft#62693

## Problem

When a generic function has overloads with mixed parameter types (function vs object literal), TypeScript shows incorrect completions for object literals. For example:

```typescript
declare function task<T>(make: () => T): void
declare function task<T>(arg: {make: () => T}): void

task({
    // BUG: Shows bind, call, apply instead of "make"
})
```

The editor shows function properties (bind, call, apply) instead of the expected object property "make".

## Root Cause

During completion, generic type inference is blocked (type parameters are unknown). When `chooseOverload` evaluates candidates, it:

1. Attempts to resolve the function-type overload first
2. Cannot infer `T` during completion context
3. Falls back to treating the object literal as a function type
4. Returns function properties instead of object properties

The issue occurs because overload selection doesn't account for the syntactic context (completing an object literal) when generic inference is unavailable.

## Solution

The fix tracks which argument position is being completed and uses this information during overload resolution to prefer object-type overloads when completing object literals.

### Changes

**types.ts (line 6311):**
Added `completionArgumentIndex` to NodeLinks to track which argument is being completed.

**checker.ts (lines 32072-32076):**
Store the argument index when inference is blocked during completion:
```typescript
if (isInferencePartiallyBlocked) {
    links.completionArgumentIndex = argIndex;
}
```

**checker.ts (lines 36728-36832):**
Enhanced `chooseOverload` to:
1. Detect when completing an object literal at argument position 0
2. Skip overload candidates with function-type parameters
3. Accept object-type overload candidates even if the literal is incomplete

This allows the type checker to select the correct overload based on syntactic context rather than relying solely on type inference.

## Why This Works

The fix is surgical and only affects generic overload resolution during completion:

- **Targeted scope:** Only triggers for object literals at argument 0 with blocked inference
- **Preserved behavior:** Non-generic overloads and other arguments remain unchanged
- **Syntactic guidance:** Uses the object literal syntax to disambiguate overloads when type inference is unavailable

The approach respects TypeScript's existing completion infrastructure while providing better overload selection for this specific edge case.

## Testing

Added comprehensive test coverage in `completionForGenericOverloadObjectLiteral.ts`:
- Generic function-first overload (the bug)
- Generic object-first overload (control)
- Non-generic overload (control)
- Multiple type parameters with optional properties (rigorous)

All tests verify that object properties appear in completions and function properties (bind, call, apply) are correctly excluded.

Test results: 99,000 passing, 0 regressions
@typescript-bot
Copy link
Copy Markdown
Collaborator

With 6.0 out as the final release vehicle for this codebase, we're closing all PRs that don't fit the merge criteria for post-6.0 patches. If you think this was a mistake and this PR fits the post-6.0 patch criteria, please post to the 6.0 iteration issue with details (specifically, which PR and which patch criteria it satisfies).

Next steps for PRs:

  • For crash bugfixes or language service improvements, PRs are currently accepted at the typescript-go repo
  • Changes to type system behavior should wait until after 7.0, at which point mainline TypeScript development will resume in this repository with the Go codebase
  • Library file updates (lib.d.ts etc) continue to live in this repo or the DOM Generator repo as appropriate

@github-project-automation github-project-automation bot moved this from Not started to Done in PR Backlog Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Intellisense displays function props instead of object's in generic function overload

3 participants