[英]In typescript how do I extend a global interface with a declared function
我正在處理一個遺留的 javascript 項目,目前正在為一些更流行的函數添加 typescript 聲明.d.ts文件,以獲得更好的 vscode 類型定義。
當前設置包括所述 function 上的多個過載,它會根據這些過載選項返回一個設定值。
declare function createChild(type: "div", options?: CreateChild_Options, node?: HTMLElement): HTMLDivElement;
declare function createChild(type: "span", options?: CreateChild_Options, node?: HTMLElement): HTMLSpanElement;
declare function createChild(type: "input", options?: CreateChild_Options, node?: HTMLElement): HTMLInputElement;
我想要的是將.createChild
function 添加到返回的 HTMLElements 中。
可能它可以寫成
interface CreateChild_DivElement extends HTMLDivElement {
createChild: createChild
}
我會用CreateChild_DivElement
替換HTMLDivElement
但由於聲明的 function 未正確添加到界面而失敗(工具提示將值顯示為 any) 。
我希望的是向 typescript 接口添加一個變量。
interface CustomElement<Original> {
...Original,
createChild: createChild,
}
並像下面的例子一樣使用它
declare function createChild(type: "div", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLDivElement>;
顯然這是行不通的,只是一個例子。
我如何獲得聲明的.createChild function 作為返回的 HTMlElement 的一部分。
在瀏覽了一些未回答的 typescript 問題后,我遇到了一個我不知道存在的類型聲明。 我現在得到了這個完整的代碼。 有效,但它絕對不漂亮。 有沒有更好的方法來實現這一點?
export = createChild;
// Declare the functions
declare function createChild(type: "div", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLDivElement>;
declare function createChild(type: "span", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLSpanElement>;
declare function createChild(type: "input", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLInputElement>;
declare function createChild(type: "p", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLParagraphElement>;
declare function createChild(type: "a", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLAnchorElement>;
declare function createChild(type: "img", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLImageElement>;
declare function createChild(type: "ul", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLUListElement>;
declare function createChild(type: "li", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLLIElement>;
declare function createChild(type: "hr", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLHRElement>;
declare function createChild(type: "h1" | "h2" | "h3" | "h4" | "h5" | "h6", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLHeadingElement>;
declare function createChild(type: string, options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLElement>;
type CustomElement<Original> = Original & {
createChild: ((type: "div", options?: CreateChild_Options, node?: HTMLElement) => CustomElement<HTMLDivElement>) &
((type: "span", options?: CreateChild_Options, node?: HTMLElement) => CustomElement<HTMLSpanElement>) &
((type: "input", options?: CreateChild_Options, node?: HTMLElement) => CustomElement<HTMLInputElement>) &
((type: "p", options?: CreateChild_Options, node?: HTMLElement) => CustomElement<HTMLParagraphElement>) &
((type: "a", options?: CreateChild_Options, node?: HTMLElement) => CustomElement<HTMLAnchorElement>) &
((type: "img", options?: CreateChild_Options, node?: HTMLElement) => CustomElement<HTMLImageElement>) &
((type: "ul", options?: CreateChild_Options, node?: HTMLElement) => CustomElement<HTMLUListElement>) &
((type: "li", options?: CreateChild_Options, node?: HTMLElement) => CustomElement<HTMLLIElement>) &
((type: "hr", options?: CreateChild_Options, node?: HTMLElement) => CustomElement<HTMLHRElement>) &
((type: "h1" | "h2" | "h3" | "h4" | "h5" | "h6", options?: CreateChild_Options, node?: HTMLElement) => CustomElement<HTMLHeadingElement>) &
((type: string, options?: CreateChild_Options, node?: HTMLElement) => CustomElement<HTMLElement>);
};
type ElementNames = 'div' | 'span' | 'input' | 'p' | 'i' | 'a' | 'img' | 'ul' | 'li' | 'hr' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
/**
* The options for create child
*/
interface CreateChild_Options {
id?: string,
classList?: string[],
style?: CSSStyleDeclaration | string,
childNodes?: (CreateChild_Create | CreateChild_Child)[],
on: {
click: (this: HTMLElement, ev: MouseEvent, options: boolean | AddEventListenerOptions) => any,
contextmenu: (this: HTMLElement, ev: MouseEvent, options: boolean | AddEventListenerOptions) => any,
keyup: (this: HTMLElement, ev: KeyboardEvent, options: boolean | AddEventListenerOptions) => any,
keydown: (this: HTMLElement, ev: KeyboardEvent, options: boolean | AddEventListenerOptions) => any,
keypress: (this: HTMLElement, ev: KeyboardEvent, options: boolean | AddEventListenerOptions) => any,
focus: (this: HTMLElement, ev: FocusEvent, options: boolean | AddEventListenerOptions) => any,
blur: (this: HTMLElement, ev: FocusEvent, options: boolean | AddEventListenerOptions) => any,
focusin: (this: HTMLElement, ev: FocusEvent, options: boolean | AddEventListenerOptions) => any,
focusout: (this: HTMLElement, ev: FocusEvent, options: boolean | AddEventListenerOptions) => any,
[key: string]: (this: HTMLElement, ev: Event, options: boolean | AddEventListenerOptions) => any,
}
};
/**
* Used create child to create and append a new child element
*/
interface CreateChild_Create {
type: ElementNames,
options?: CreateChild_Options,
}
/**
* appends a child element that was created already
*/
interface CreateChild_Child {
child: HTMLElement | HTMLNode
}
包含 function 聲明的文件是一個模塊。
模塊是包含一個或多個頂級import
或export
語句的文件。
您的文件包含
export = createChild;
使其成為一個模塊。
在模塊中以詞法方式指定的所有構造,無論它們是值還是類型,環境與否,都在該模塊的范圍內。
但是,有時我們需要從模塊中伸出一些東西到封閉的 scope 中,對於一個模塊來說,它是全局 scope。
對於值,我們照你說的做,並分配給window
或global
或globalThis
的屬性。 由於 TypeScript 將類型添加到 JavaScript 它需要一種語法來使我們能夠對類型執行相同的操作。
該語法是declare global
塊。
在下面的代碼中,它應用於您的示例,
export = createChild;
declare global {
function createChild(type: "div", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLDivElement>;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.