microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.45k stars 12.42k forks source link

Feature that displays method argument names inline does not correctly handle method overloading (so variable name is taken from bad overload, probably from the first method definition). #59463

Open scr4bble opened 2 months ago

scr4bble commented 2 months ago

Type: Bug

When having code like this:

  public async cancelBooking(
    internalBookingId: number,
    company: Companies,
    dataStoreService: DataStoreService,
    bookingsService: BookingsService,
  ): Promise<void>;
  public async cancelBooking(
    booking: ExtendedBookingSystemBooking,
    company: Companies,
    dataStoreService: DataStoreService,
    bookingsService: BookingsService,
  ): Promise<void>;
  public async cancelBooking(
    booking: number | ExtendedBookingSystemBooking,
    company: Companies,
    dataStoreService: DataStoreService,
    bookingsService: BookingsService,
  ) {
    ...
  }

And then calling this method from other part in the code && using ExtendedBookingSystemBooking for the first argument, the inline method argument hinting shows "internalBookingId" as method argument name despite VSCode knows the second method definition is used (shows this correctly when hovering over the method call).

VS Code version: Code 1.91.1 (f1e16e1e6214d7c44d078b1f0607b2388f29d729, 2024-07-09T22:08:12.169Z) OS version: Linux x64 6.9.9-100.fc39.x86_64 Modes:

System Info |Item|Value| |---|---| |CPUs|Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz (8 x 2899)| |GPU Status|2d_canvas: enabled
canvas_oop_rasterization: disabled_off
direct_rendering_display_compositor: disabled_off_ok
gpu_compositing: enabled
multiple_raster_threads: enabled_on
opengl: enabled_on
rasterization: enabled
raw_draw: disabled_off_ok
skia_graphite: disabled_off
video_decode: enabled
video_encode: disabled_software
vulkan: disabled_off
webgl: enabled
webgl2: enabled
webgpu: disabled_off| |Load (avg)|2, 3, 3| |Memory (System)|31.23GB (11.54GB free)| |Process Argv|--crash-reporter-id 42f3b124-3ec4-47eb-9930-f9dae9c4e9d6| |Screen Reader|no| |VM|0%| |DESKTOP_SESSION|gnome-xorg| |XDG_CURRENT_DESKTOP|GNOME| |XDG_SESSION_DESKTOP|gnome-xorg| |XDG_SESSION_TYPE|x11|
Extensions (15) Extension|Author (truncated)|Version ---|---|--- atlascode|atl|3.0.10 vscode-eslint|dba|3.0.10 gitlens|eam|15.2.3 prettier-vscode|esb|10.4.0 auto-rename-tag|for|0.1.10 lintlens|ghm|7.5.0 copilot|Git|1.219.0 copilot-chat|Git|0.17.1 vscode-pull-request-github|Git|0.92.0 vscode-graphql|Gra|0.11.0 vscode-graphql-syntax|Gra|1.3.6 todo-tree|Gru|0.0.226 intellij-idea-keybindings|k--|1.7.2 vscode-speech|ms-|0.10.0 vscode-yaml|red|1.15.0 (2 theme extensions excluded)
A/B Experiments ``` vsliv368cf:30146710 vspor879:30202332 vspor708:30202333 vspor363:30204092 vswsl492:30256859 vstes627:30244334 vscorecescf:30445987 vscod805cf:30301675 binariesv615:30325510 vsaa593cf:30376535 py29gd2263:31024239 vscaat:30438848 c4g48928:30535728 azure-dev_surveyone:30548225 962ge761:30959799 pythongtdpath:30769146 welcomedialog:30910333 pythonnoceb:30805159 asynctok:30898717 pythonregdiag2:30936856 pythonmypyd1:30879173 2e7ec940:31000449 pythontbext0:30879054 accentitlementst:30995554 dsvsc016:30899300 dsvsc017:30899301 dsvsc018:30899302 cppperfnew:31000557 dsvsc020:30976470 pythonait:31006305 dsvsc021:30996838 724cj586:31013169 pythoncenvpt:31062603 a69g1124:31058053 dvdeprecation:31068756 dwnewjupyter:31046869 impr_priority:31102340 refactort:31101459 pythonrstrctxtcf:31093870 wkspc-onlycs-t:31102394 ```
scr4bble commented 2 months ago

image

RyanCavanaugh commented 2 months ago

I can't repro this. Can you post a code sample we can look at locally that demonstrates this problem?

What I tried:

Image

declare function foo(str: string): void;
declare function foo(num: number): void;

foo("string");

foo(12345);
scr4bble commented 2 months ago

Hi @RyanCavanaugh - it probably works fine for simpler cases. Try to use this "minimal" reproducer please:

class ZZZ {
  id: number;
}

class CCC {
  activities: number[];
}

class XYZ {
  public async cancelBooking(
    internalBookingId: number,
    company: ZZZ,
  ): Promise<void>;
  public async cancelBooking(booking: CCC, company: ZZZ): Promise<void>;
  public async cancelBooking(booking: number | CCC, company: ZZZ) {}

  public async XYZ() {
    return this.cancelBooking(
      { activities: [1, 2, 3] },
      {
        id: 1,
      },
    );
  }
}
RyanCavanaugh commented 2 months ago
type HasID = {
  id: number;
}

type Numbers = {
  n: number[];
}

declare function func(bad1: number, bad2: HasID): void;
declare function func(ok_1: Numbers, ok_2: HasID): void;

// Inlay hint shows bad1/bad2, should show ok_1/ok_2
func(
  { n: [1, 2, 3] },
  {
    id: 1,
  },
);