Repository: TypeScript
Issue: Show comments from properties referenced via 'keyof T'
Labels: Suggestion,In Discussion

## Search Terms

comments, keyof

## Suggestion

The goal would be to improve Quick Info using code comments extracted from members via a generic `keyof T` when used as part of a call expression.

Consider the following two cases:

```ts
// old way of writing events (since forever)
interface Evented1 {
  /** Handles the 'click' event. */
  on(type: "click", listener: (args: ClickEvent) => void): this;
  /** Handles the 'mousedown' event. */
  on(type: "mousedown", listener: (args: MouseDownEvent) => void): this;
  // ...
}

declare const obj1: Evented1;
obj1.on("click", _ => {}); // shows 'Handles the 'click' event in quickinfo when hovering over 'on'.
obj1.on("mousedown", _ => {}); // shows 'Handles the 'mousedown' event in quickinfo when hovering over 'on'.


// new way of events (used in lib.dom, may end up being used in Node at some point)...
interface Evented2EventMap {
  /** Handles the 'click' event. */
  click: ClickEvent;
  /** Handles the 'mousedown' event. */
  mousedown: MouseDownEvent;
  // ...
}

interface Evented2 {
  on<K extends keyof Evented2EventMap>(type: K, listener: (args: Evented2EventMap[K]) => void): this;
}

declare const obj2: Evented2;
obj2.on("click", _ => {}); // no comments when hovering over 'on'.
obj2.on("mousedown", _ => {}); // no comments when hovering over 'on'.
```

## Use Cases

Improving quick-info for event-based methods like `on`/`addListener`/`addEventListener` (i.e. for `EventEmitter`, `EventTarget`, etc.) and messaging based methods like `send` (on message ports, websockets, etc.).

Additionally, we could leverage our new `@deprecated` JSDoc-tag support to flag calls when a generic argument refers to a member name that has been marked with `@deprecated`.

## Examples

```ts
interface RequestMap {
  /** @deprecated Misspelled, use `AddItem` instead. */
  AddIetm: [AddItemRequest, AddItemResponse];

  /** Adds a new item to the collection */
  AddItem: [AddItemRequest, AddItemResponse];
}

interface EventMap {
  /** Raised whenever an item is added to the collection. **/
  CollectionChanged: CollectionChangedEventArgs;
}

interface Service {
  /** Sends a request to the service. */
  send<K extends keyof RequestMap>(type: K, args: RequestMap[K][0]): Promise<RequestMap[K][1]>;

  /** Listens for an event from the service. */
  on<K extends keyof EventMap>(type: K, listener: (args: EventMap[K]) => void): this;
}

declare const svc: Service;
```

**Quick Info for `send`:**
```ts
service.send("AddItem", { }); 
```
> ```ts
> (method) Service.send<"AddItem">(type: "AddItem", args: AddItemRequest): Promise<AddItemResponse>
> ```
> Sends a request to the service.
>
> Adds a new item to the collection.

**Quick Info for `send` with deprecation:**
<pre>
<code>service.send(</code><del><code>"AddIetm"</code></del><code>, {});</code>
</pre>
> ```ts
> (method) Service.send<"AddIetm">(type: "AddIetm", args: AddItemRequest): Promise<AddItemResponse>
> ```
> Sends a request to the service.
>
> @deprecated - Misspelled, use `AddItem` instead.

**Quick Info for `on`:**
```ts
service.on("CollectionChanged", args => {});
```
> ```ts
> (method) Service.on<"CollectionChanged">(type: "CollectionChanged", listener: (args: CollectionChangedEventArgs) => void): Service
> ```
> Listens for an event from the service.
>
> Raised whenever an item is added to the collection.

## Checklist

My suggestion meets these guidelines:

* [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [x] This wouldn't change the runtime behavior of existing JavaScript code
* [x] This could be implemented without emitting different JS based on the types of the expressions
* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).

## Related Issues

- #31992 - Preserve comments when using Extract<keyof T, string>
- #41165 - 'Documented' Utility Type