我正在研究一个旧式javascript项目,目前正在为一些较流行的功能添加打字稿声明 .d.ts 文件,以更好地进行vscode类型定义。
当前设置在该函数中包含多个重载,并根据这些重载选项返回一个设置值。
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
函数添加到要返回的HTMLElements中。
可能它可以写为
interface CreateChild_DivElement extends HTMLDivElement {
createChild: createChild
}
,而我将HTMLDivElement
替换为CreateChild_DivElement
,但是由于声明的函数未正确添加到接口(工具提示将值显示为任意值)而失败。
我希望为打字稿界面添加一个变量。
interface CustomElement<Original> {
...Original,
createChild: createChild,
}
并像下面的示例一样使用它
declare function createChild(type: "div", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLDivElement>;
显然这是行不通的,仅是示例。
如何将声明的.createChild函数作为返回的HTMlElement的一部分。
浏览了一些未解决的打字稿问题后,我遇到了一个我不知道存在的类型声明。现在,我得到了完整的代码。可行,但绝对不是很漂亮。有没有更好的方法可以达到这个目的?
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
}
答案 0 :(得分:0)
包含函数声明的文件是一个模块。
模块是包含一个或多个顶级import
或export
语句的文件。
您的文件包含
export = createChild;
使其成为模块。
在模块中按词法指定的所有构造,无论它们的值或类型(是否为环境),都限于该模块。
但是,有时我们需要从模块内部伸出手,以便将某些东西添加到封闭的作用域中,对于模块来说,这就是全局作用域。
对于值,我们按照您所说的进行操作,并将其分配给window
或global
或globalThis
的属性。当TypeScript将类型添加到JavaScript时,它需要一种语法来使我们能够对类型执行相同的操作。
该语法为declare global
块。
在下面的代码中,该代码将应用于您的示例,
export = createChild;
declare global {
function createChild(type: "div", options?: CreateChild_Options, node?: HTMLElement): CustomElement<HTMLDivElement>;
}