microsoft / microsoft/TypeScript

keyof T should never print as a union of strings

オープン
#33,254 コメント 4 件 リアクション 1 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

In Discussion Suggestion
主要言語
Go
スター
111k
フォーク
14.4k
平均マージ
1日 19時間
マージ済み PR(30日)
117

説明

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;

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

リポジトリのファイルもテストパスも記載されていません。提供されたスニペットと TypeScript 3.6.2 を使って問題を再現し、その後、ジェネリック制約がどこで展開されるのかを特定するために、宣言生成と型の出力を追跡してください。生成された宣言がイベント名のユニオンを出力するのではなく、K を keyof HTMLElementEventMap を拡張するものとして保持すれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
typescript
領域
compilers
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
明確に書かれている
初心者へのやさしさ
38/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。