microsoft / microsoft/TypeScript
keyof T should never print as a union of strings
Open
Nobody has claimed this yet.
In Discussion
Suggestion
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
TypeScript Version: 3.6.2
Search Terms: extends keyof generic
Code
export const bindEvent = <Node extends HTMLElement | HTMLDocument,
K extends keyof HTMLElementEventMap>(
node: Node,
type: K,
callback: (event: HTMLElementEventMap[K]) => unknown,
) => {
node.addEventListener(type, callback as EventListener);
return () => {
node.removeEventListener(type, callback as EventListener);
};
};
tsc
Expected behavior:
The generic K to still be extends keyof, instead of spreading the type out.
Actual behavior:
types generated:
export declare const bindEvent: <Node_1 extends HTMLElement | HTMLDocument, K extends "fullscreenchange" | "fullscreenerror" | "abort" | "animationcancel" | "animationend" | "animationiteration" | "animationstart" | "auxclick" | "blur" | "cancel" | "canplay" | "canplaythrough" | "change" | "click" | "close" | "contextmenu" | "cuechange" | "dblclick" | "drag" | "dragend" | "dragenter" | "dragexit" | "dragleave" | "dragover" | "dragstart" | "drop" | "durationchange" | "emptied" | "ended" | "error" | "focus" | "focusin" | "focusout" | "gotpointercapture" | "input" | "invalid" | "keydown" | "keypress" | "keyup" | "load" | "loadeddata" | "loadedmetadata" | "loadend" | "loadstart" | "lostpointercapture" | "mousedown" | "mouseenter" | "mouseleave" | "mousemove" | "mouseout" | "mouseover" | "mouseup" | "pause" | "play" | "playing" | "pointercancel" | "pointerdown" | "pointerenter" | "pointerleave" | "pointermove" | "pointerout" | "pointerover" | "pointerup" | "progress" | "ratechange" | "reset" | "resize" | "scroll" | "securitypolicyviolation" | "seeked" | "seeking" | "select" | "selectionchange" | "selectstart" | "stalled" | "submit" | "suspend" | "timeupdate" | "toggle" | "touchcancel" | "touchend" | "touchmove" | "touchstart" | "transitioncancel" | "transitionend" | "transitionrun" | "transitionstart" | "volumechange" | "waiting" | "wheel" | "copy" | "cut" | "paste">(node: Node_1, type: K, callback: (event: HTMLElementEventMap[K]) => unknown) => () => void;
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No repository file or test path is mentioned. Reproduce the issue with the provided snippet and TypeScript 3.6.2, then trace declaration generation and type printing to identify where the generic constraint is expanded. Done means the generated declaration preserves K as extending keyof HTMLElementEventMap rather than printing the union of event names.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100