Skip to content

Commit

Permalink
JSX Prototype Omit + JSDoc Borrows
Browse files Browse the repository at this point in the history
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 )
microsoft/TypeScript#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
  • Loading branch information
Offroaders123 committed Nov 22, 2023
1 parent cc01856 commit 0585a75
Show file tree
Hide file tree
Showing 2 changed files with 347 additions and 0 deletions.
11 changes: 11 additions & 0 deletions 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<HTMLElementTagNameMap[K]>;
};

declare const gg: noice["a"];
336 changes: 336 additions & 0 deletions 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"
]
})

0 comments on commit 0585a75

Please sign in to comment.