From 0585a752ad7bb6550d9976ea3c4f501f6fb325f6 Mon Sep 17 00:00:00 2001 From: Offroaders123 <65947371+Offroaders123@users.noreply.github.com> Date: Tue, 21 Nov 2023 21:10:30 -0800 Subject: [PATCH] JSX Prototype Omit + JSDoc Borrows Realized it would make sense if my automatic JSX types could have their JSDoc annotation descriptions from the base `HTMLElement`-kind of interface definitions they are already based on, but that doesn't appear to be possible for mapped types unfortunately. https://jsdoc.app/tags-borrows https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#link (this is an alternative, where `@borrows` won't work [i'm not sure if it works in TS anyways, but yeah], `@link` is a nice alternative if that eventually does work :) ) https://stackoverflow.com/questions/70766995/how-can-i-link-something-that-isnt-imported (not related specifically, but neat otherwise :D ) https://github.com/microsoft/TypeScript/issues/50715 The next thing I thought of is that an option to get automatic types for JSX element definitions based on `HTMLElement`-based interfaces more narrowed than it currently is. Right now it lets you assign attributes that are readonly, and also assign to element methods, which isn't ideal. It could just be 'ignored', but this defeats the purpose of TypeScript, which should prevent accidentally overriding that kind of thing. Most JSX types implementations declare their own types for the element creation, I think that's a big extra though, in terms at least with what and why I'm trying to work on this library. Since it's creating standard elements, I think it makes a lot of sense to derive the JSX types from those dynamically, hence that will also allow you to get automatic type definitions for Web Component classes, and it will work without the implementor of that component to provide their own JSX types for this project. The key is that it works in your favor, you don't need to make it work with this tool. (Inspired behind the TypeScript origin story; https://www.youtube.com/watch?v=U6s2pdxebSo&t=2200s) Since the types for the `HTMLElement` prototype tree are essentially a static list of members (the only difference being new features added down the line), it seems feasible to omit specific keys which shouldn't be assignable/visible in JSX, simply by removing keys that are present in parent prototypes of the base `HTMLElement` class. I went up the prototype tree to get `HTMLElement > Element > Node > EventTarget > Object`. Now I can go through these values to deduce which ones can be removed from the JSX types, hence allowing only the necessary ones to be accessible from the user's point of view when assigning props and such. https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys --- jsx/src/borrow-docs.ts | 11 ++ jsx/src/prototypes.ts | 336 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 347 insertions(+) create mode 100644 jsx/src/borrow-docs.ts create mode 100644 jsx/src/prototypes.ts diff --git a/jsx/src/borrow-docs.ts b/jsx/src/borrow-docs.ts new file mode 100644 index 0000000..74c6d1f --- /dev/null +++ b/jsx/src/borrow-docs.ts @@ -0,0 +1,11 @@ +export type gg = 5; + +/** {@link gg} */ +export type aa = "noice"; + +export type noice = { + /** {@link HTMLElementTagNameMap[K]} */ + [K in keyof HTMLElementTagNameMap]: Partial; +}; + +declare const gg: noice["a"]; \ No newline at end of file diff --git a/jsx/src/prototypes.ts b/jsx/src/prototypes.ts new file mode 100644 index 0000000..be50cd5 --- /dev/null +++ b/jsx/src/prototypes.ts @@ -0,0 +1,336 @@ +// ({ +// Object: Object.keys(Object.prototype), +// EventTarget: Object.keys(EventTarget.prototype), +// Node: Object.keys(Node.prototype), +// Element: Object.keys(Element.prototype), +// HTMLElement: Object.keys(HTMLElement.prototype) +// }) + +({ + Object: [], + EventTarget: [ + "addEventListener", + "dispatchEvent", + "removeEventListener" + ], + Node: [ + "nodeType", + "nodeName", + "baseURI", + "isConnected", + "ownerDocument", + "parentNode", + "parentElement", + "childNodes", + "firstChild", + "lastChild", + "previousSibling", + "nextSibling", + "nodeValue", + "textContent", + "ELEMENT_NODE", + "ATTRIBUTE_NODE", + "TEXT_NODE", + "CDATA_SECTION_NODE", + "ENTITY_REFERENCE_NODE", + "ENTITY_NODE", + "PROCESSING_INSTRUCTION_NODE", + "COMMENT_NODE", + "DOCUMENT_NODE", + "DOCUMENT_TYPE_NODE", + "DOCUMENT_FRAGMENT_NODE", + "NOTATION_NODE", + "DOCUMENT_POSITION_DISCONNECTED", + "DOCUMENT_POSITION_PRECEDING", + "DOCUMENT_POSITION_FOLLOWING", + "DOCUMENT_POSITION_CONTAINS", + "DOCUMENT_POSITION_CONTAINED_BY", + "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC", + "appendChild", + "cloneNode", + "compareDocumentPosition", + "contains", + "getRootNode", + "hasChildNodes", + "insertBefore", + "isDefaultNamespace", + "isEqualNode", + "isSameNode", + "lookupNamespaceURI", + "lookupPrefix", + "normalize", + "removeChild", + "replaceChild" + ], + Element: [ + "namespaceURI", + "prefix", + "localName", + "tagName", + "id", + "className", + "classList", + "slot", + "attributes", + "shadowRoot", + "part", + "assignedSlot", + "innerHTML", + "outerHTML", + "scrollTop", + "scrollLeft", + "scrollWidth", + "scrollHeight", + "clientTop", + "clientLeft", + "clientWidth", + "clientHeight", + "onbeforecopy", + "onbeforecut", + "onbeforepaste", + "onsearch", + "elementTiming", + "onfullscreenchange", + "onfullscreenerror", + "onwebkitfullscreenchange", + "onwebkitfullscreenerror", + "role", + "ariaAtomic", + "ariaAutoComplete", + "ariaBusy", + "ariaBrailleLabel", + "ariaBrailleRoleDescription", + "ariaChecked", + "ariaColCount", + "ariaColIndex", + "ariaColSpan", + "ariaCurrent", + "ariaDescription", + "ariaDisabled", + "ariaExpanded", + "ariaHasPopup", + "ariaHidden", + "ariaInvalid", + "ariaKeyShortcuts", + "ariaLabel", + "ariaLevel", + "ariaLive", + "ariaModal", + "ariaMultiLine", + "ariaMultiSelectable", + "ariaOrientation", + "ariaPlaceholder", + "ariaPosInSet", + "ariaPressed", + "ariaReadOnly", + "ariaRelevant", + "ariaRequired", + "ariaRoleDescription", + "ariaRowCount", + "ariaRowIndex", + "ariaRowSpan", + "ariaSelected", + "ariaSetSize", + "ariaSort", + "ariaValueMax", + "ariaValueMin", + "ariaValueNow", + "ariaValueText", + "children", + "firstElementChild", + "lastElementChild", + "childElementCount", + "previousElementSibling", + "nextElementSibling", + "after", + "animate", + "append", + "attachShadow", + "before", + "closest", + "computedStyleMap", + "getAttribute", + "getAttributeNS", + "getAttributeNames", + "getAttributeNode", + "getAttributeNodeNS", + "getBoundingClientRect", + "getClientRects", + "getElementsByClassName", + "getElementsByTagName", + "getElementsByTagNameNS", + "getInnerHTML", + "hasAttribute", + "hasAttributeNS", + "hasAttributes", + "hasPointerCapture", + "insertAdjacentElement", + "insertAdjacentHTML", + "insertAdjacentText", + "matches", + "prepend", + "querySelector", + "querySelectorAll", + "releasePointerCapture", + "remove", + "removeAttribute", + "removeAttributeNS", + "removeAttributeNode", + "replaceChildren", + "replaceWith", + "requestFullscreen", + "requestPointerLock", + "scroll", + "scrollBy", + "scrollIntoView", + "scrollIntoViewIfNeeded", + "scrollTo", + "setAttribute", + "setAttributeNS", + "setAttributeNode", + "setAttributeNodeNS", + "setPointerCapture", + "toggleAttribute", + "webkitMatchesSelector", + "webkitRequestFullScreen", + "webkitRequestFullscreen", + "checkVisibility", + "getAnimations" + ], + HTMLElement: [ + "title", + "lang", + "translate", + "dir", + "hidden", + "accessKey", + "draggable", + "spellcheck", + "autocapitalize", + "contentEditable", + "enterKeyHint", + "isContentEditable", + "inputMode", + "virtualKeyboardPolicy", + "offsetParent", + "offsetTop", + "offsetLeft", + "offsetWidth", + "offsetHeight", + "popover", + "innerText", + "outerText", + "onbeforexrselect", + "onabort", + "onbeforeinput", + "onbeforetoggle", + "onblur", + "oncancel", + "oncanplay", + "oncanplaythrough", + "onchange", + "onclick", + "onclose", + "oncontextlost", + "oncontextmenu", + "oncontextrestored", + "oncuechange", + "ondblclick", + "ondrag", + "ondragend", + "ondragenter", + "ondragleave", + "ondragover", + "ondragstart", + "ondrop", + "ondurationchange", + "onemptied", + "onended", + "onerror", + "onfocus", + "onformdata", + "oninput", + "oninvalid", + "onkeydown", + "onkeypress", + "onkeyup", + "onload", + "onloadeddata", + "onloadedmetadata", + "onloadstart", + "onmousedown", + "onmouseenter", + "onmouseleave", + "onmousemove", + "onmouseout", + "onmouseover", + "onmouseup", + "onmousewheel", + "onpause", + "onplay", + "onplaying", + "onprogress", + "onratechange", + "onreset", + "onresize", + "onscroll", + "onsecuritypolicyviolation", + "onseeked", + "onseeking", + "onselect", + "onslotchange", + "onstalled", + "onsubmit", + "onsuspend", + "ontimeupdate", + "ontoggle", + "onvolumechange", + "onwaiting", + "onwebkitanimationend", + "onwebkitanimationiteration", + "onwebkitanimationstart", + "onwebkittransitionend", + "onwheel", + "onauxclick", + "ongotpointercapture", + "onlostpointercapture", + "onpointerdown", + "onpointermove", + "onpointerrawupdate", + "onpointerup", + "onpointercancel", + "onpointerover", + "onpointerout", + "onpointerenter", + "onpointerleave", + "onselectstart", + "onselectionchange", + "onanimationend", + "onanimationiteration", + "onanimationstart", + "ontransitionrun", + "ontransitionstart", + "ontransitionend", + "ontransitioncancel", + "oncopy", + "oncut", + "onpaste", + "dataset", + "nonce", + "autofocus", + "tabIndex", + "style", + "attributeStyleMap", + "attachInternals", + "blur", + "click", + "focus", + "hidePopover", + "showPopover", + "togglePopover", + "inert", + "oncontentvisibilityautostatechange", + "onscrollend", + "onbeforematch" + ] +}) \ No newline at end of file