Repository navigation
Show comments from properties referenced via 'keyof T' #41220
Description
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:
// 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
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:
service.send("AddItem", { }); (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:
service.send("AddIetm", {});
(method) Service.send<"AddIetm">(type: "AddIetm", args: AddItemRequest): Promise<AddItemResponse>Sends a request to the service.
Daniel Edeling (@deprecated) - Misspelled, use
AddIteminstead.
Quick Info for on:
service.on("CollectionChanged", args => {});(method) Service.on<"CollectionChanged">(type: "CollectionChanged", listener: (args: CollectionChangedEventArgs) => void): ServiceListens for an event from the service.
Raised whenever an item is added to the collection.
Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
Related Issues
- [Feature Request] Preserve comments when using Extract<keyof T, string> #31992 - Preserve comments when using Extract<keyof T, string>
- Feature Request:
DocumentedUtility Type #41165 - 'Documented' Utility Type
Activity
tjjfvi commentedon Oct 24, 2020
While this would definitely be a step in the right direction, I think that #41165 might do a better job at representing all use cases, as it allows developers to specify their intent, rather than assuming it for them.
I think there are some cases where the default behavior wouldn't always make sense; for example, how are
asclauses handled? If the key gets changed, there are times when the documentation would no longer make sense. In other cases, theasclause is only to filter, and so the documentation should be transferred.I am not very familiar with how jsdoc is handled internally; if you or someone else with familiarity could address this and the ideas in #41165, that would be awesome.