Typescript: 如何禁止将Omit转化为Pick,当使用generic?

问题描述 投票:1回答:1

如何禁止这种行为?当你只为库编译类型声明时,这是一个关键问题。

我需要它只用于编译声明。

tsc --declaration true --emitDeclarationOnly true

最简单的代码示例。

function test<T>(t: T): Omit<T, 'href'> {
  return t;
}

export const TEST_CONST = test({} as HTMLAnchorElement);

期待:

export declare const TEST_CONST: Omit<HTMLAnchorElement, 'href'>

已收到:

export declare const TEST_CONST: Pick<HTMLAnchorElement, "toString" | "search" | "normalize" | "host" | "password" | "origin" | "hidden" | "dir" | "slot" | "style" | "title" | "text" | "blur" | "click" | "focus" | "scroll" | "attributes" | "after" | "animate" | "accessKey" | "className" | "contentEditable" | "draggable" | "id" | "lang" | "tabIndex" | "translate" | "prefix" | "inputMode" | "download" | "href" | "ping" | "rel" | "target" | "type" | "referrerPolicy" | "name" | "charset" | "coords" | "hreflang" | "relList" | "rev" | "shape" | "addEventListener" | "removeEventListener" | "accessKeyLabel" | "autocapitalize" | "innerText" | "offsetHeight" | "offsetLeft" | "offsetParent" | "offsetTop" | "offsetWidth" | "spellcheck" | "assignedSlot" | "classList" | "clientHeight" | "clientLeft" | "clientTop" | "clientWidth" | "localName" | "namespaceURI" | "onfullscreenchange" | "onfullscreenerror" | "outerHTML" | "ownerDocument" | "scrollHeight" | "scrollLeft" | "scrollTop" | "scrollWidth" | "shadowRoot" | "tagName" | "attachShadow" | "closest" | "getAttribute" | "getAttributeNS" | "getAttributeNames" | "getAttributeNode" | "getAttributeNodeNS" | "getBoundingClientRect" | "getClientRects" | "getElementsByClassName" | "getElementsByTagName" | "getElementsByTagNameNS" | "hasAttribute" | "hasAttributeNS" | "hasAttributes" | "hasPointerCapture" | "insertAdjacentElement" | "insertAdjacentHTML" | "insertAdjacentText" | "matches" | "msGetRegionContent" | "releasePointerCapture" | "removeAttribute" | "removeAttributeNS" | "removeAttributeNode" | "requestFullscreen" | "requestPointerLock" | "scrollBy" | "scrollIntoView" | "scrollTo" | "setAttribute" | "setAttributeNS" | "setAttributeNode" | "setAttributeNodeNS" | "setPointerCapture" | "toggleAttribute" | "webkitMatchesSelector" | "baseURI" | "childNodes" | "firstChild" | "isConnected" | "lastChild" | "nextSibling" | "nodeName" | "nodeType" | "nodeValue" | "parentElement" | "parentNode" | "previousSibling" | "textContent" | "appendChild" | "cloneNode" | "compareDocumentPosition" | "contains" | "getRootNode" | "hasChildNodes" | "insertBefore" | "isDefaultNamespace" | "isEqualNode" | "isSameNode" | "lookupNamespaceURI" | "lookupPrefix" | "removeChild" | "replaceChild" | "ATTRIBUTE_NODE" | "CDATA_SECTION_NODE" | "COMMENT_NODE" | "DOCUMENT_FRAGMENT_NODE" | "DOCUMENT_NODE" | "DOCUMENT_POSITION_CONTAINED_BY" | "DOCUMENT_POSITION_CONTAINS" | "DOCUMENT_POSITION_DISCONNECTED" | "DOCUMENT_POSITION_FOLLOWING" | "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC" | "DOCUMENT_POSITION_PRECEDING" | "DOCUMENT_TYPE_NODE" | "ELEMENT_NODE" | "ENTITY_NODE" | "ENTITY_REFERENCE_NODE" | "NOTATION_NODE" | "PROCESSING_INSTRUCTION_NODE" | "TEXT_NODE" | "dispatchEvent" | "getAnimations" | "before" | "remove" | "replaceWith" | "innerHTML" | "nextElementSibling" | "previousElementSibling" | "childElementCount" | "firstElementChild" | "lastElementChild" | "append" | "prepend" | "querySelector" | "querySelectorAll" | "oncopy" | "oncut" | "onpaste" | "isContentEditable" | "onabort" | "onanimationcancel" | "onanimationend" | "onanimationiteration" | "onanimationstart" | "onauxclick" | "onblur" | "oncancel" | "oncanplay" | "oncanplaythrough" | "onchange" | "onclick" | "onclose" | "oncontextmenu" | "oncuechange" | "ondblclick" | "ondrag" | "ondragend" | "ondragenter" | "ondragexit" | "ondragleave" | "ondragover" | "ondragstart" | "ondrop" | "ondurationchange" | "onemptied" | "onended" | "onerror" | "onfocus" | "ongotpointercapture" | "oninput" | "oninvalid" | "onkeydown" | "onkeypress" | "onkeyup" | "onload" | "onloadeddata" | "onloadedmetadata" | "onloadstart" | "onlostpointercapture" | "onmousedown" | "onmouseenter" | "onmouseleave" | "onmousemove" | "onmouseout" | "onmouseover" | "onmouseup" | "onpause" | "onplay" | "onplaying" | "onpointercancel" | "onpointerdown" | "onpointerenter" | "onpointerleave" | "onpointermove" | "onpointerout" | "onpointerover" | "onpointerup" | "onprogress" | "onratechange" | "onreset" | "onresize" | "onscroll" | "onsecuritypolicyviolation" | "onseeked" | "onseeking" | "onselect" | "onselectionchange" | "onselectstart" | "onstalled" | "onsubmit" | "onsuspend" | "ontimeupdate" | "ontoggle" | "ontouchcancel" | "ontouchend" | "ontouchmove" | "ontouchstart" | "ontransitioncancel" | "ontransitionend" | "ontransitionrun" | "ontransitionstart" | "onvolumechange" | "onwaiting" | "onwheel" | "autofocus" | "dataset" | "nonce" | "hash" | "hostname" | "pathname" | "port" | "protocol" | "username">;

明确的类型声明可以工作,但对于大的函数调用链来说很不方便。

function test<T>(t: T): Omit<T, 'href'> {
  return t;
}

export const TEST_CONST: Omit<T, 'href'> = test({} as HTMLAnchorElement);
typescript tsc
1个回答
2
投票

这是预期和有效的值。因为 Omit 是一个 PickExclude.

/**
 * Construct a type with the properties of T except for those in type K.
 */
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

尝试为它定义自己的类型。

type NoHref<T> = Omit<T, 'href'>;

function test<T>(t: T): NoHref<T> {
  return t;
}

export const TEST_CONST = test({} as HTMLAnchorElement);
© www.soinside.com 2019 - 2024. All rights reserved.