我想使用自己的某些功能来扩展dom库,但是我希望对从HTMLElement派生的现有DOM元素进行扩展。我用window.customElements
创建的新创建的元素,它们也是从HTMLElement派生的。我将提供一些示例代码,以说明如何在打字稿类型系统中实现这一目标。
首先,我在HTMLELement接口上声明了一些常用功能,例如
interface HTMLElement{
$showPanel(Event: Event, ButtonID: number, ForceShow: boolean): boolean;
$_showPanel(Panel: any, Element: HTMLElement, PanelID: number, ForceShow: boolean): void;
getElementsByAttribute(Attribute: string, Value: string, Tag?: string):Element[];
updateView(config: {}): void;
$readonly(BReadonly: boolean): void;
$disable(Disable: boolean, AddToModelReadOnly: string): void;
atRuntime():void;
};
然后,我具有使用特定DomElement的特定属性的功能,并且需要检查给定属性在该DomElement上是否存在。我创建了一个额外的接口,用于扩展具有这些特定功能的HTML元素。
interface ElmentSpecificFunction<T> extends HTMLElement{
$sed(this:T,atb: keyof ElementSpecficProperties<T> ,val: string): CEEO<boolean>;
$set(this:T,atb: keyof ElementSpecficProperties<T> , val: string|null, dom?: boolean): CEEO<boolean>;
}
atb参数使用以下类型
type ElementSpecficProperties<T> = Pick<T,WritableKeys<T>>;
type WritableKeys<T> = {
[P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]:
T[P] }, P>
}[keyof T];
type IfEquals<X, Y, A=X, B=never> =
(<T>() => T extends X ? 1 : 2) extends
( <T>() => T extends Y ? 1 : 2) ? A : B;
这些类型只是出于我的意愿过滤掉了只读属性。
此接口将由每个Dom元素的特定接口实现 像这样
interface HTMLDivElement extends ElmentSpecificFunction<HTMLDivElement>{};
这样做,所有属性将继承标准HTML元素属性并在那里实现。
然后我编写了以下函数
$set<T>(this:ElmentSpecificFunction<T>,atb: keyof ElementSpecficProperties<ElmentSpecificFunction<T>> , val:any, dom:boolean): CEEO<boolean> {//TODO moet try catch met het Catch_Error_Object.
dom = dom || false;
try {
// let decrip = Object.getOwnPropertyDescriptor(this,atb)!;
// this.
if(val !== null ){
if( dom ) {
this.setAttribute( atb.toString(), val );
return {succes:true,error:undefined,data:true};
}
else{
this[atb] = val;
return {succes:true,error:undefined,data:true};
}
}
return {succes:false,error:new Error("value is null no set possible"),data:false}
}
catch( Error ) {
window.AE.Log("Error while setting attribute [" + atb + "] on object [" + this.id + "] where dom = [" + dom + "] and val = " + val + "\n"+ Error, "$set", true );
return {succes:false,error:Error,data:false};
}
},
我将按如下所示制作原型
HTMLDivElement.prototype.$set = $set
并像这样进行测试
let div = document.createElement("div");
div.$set("","")
但是当我使用align这样的变量时,应该不会有问题,因为当使用元素上不存在的其他名称时,它会出现在div元素上,这应该会产生一个错误,我可以使用普通的HTMLElement但希望它可用于每个特定的Dom元素。
仅当使用此类功能添加接口时,此方法才有效
div.$set<HTMDivElement>("","")
我希望这里的人知道如何执行此操作,因为这将有助于对这些函数进行类型检查。