Можно ли создавать прототипы с помощью дженериков внутри системы типов - PullRequest
0 голосов
/ 07 ноября 2018

Я хочу расширить библиотеку dom с помощью некоторой собственной функции, но я хочу это для существующих элементов DOM, которые получены из HTMLElement. И недавно созданные элементы, которые созданы мной с window.customElements и также получены из HTMLElement. Я приведу пример кода, как я хочу достичь этого внутри системы типов машинописи.

Во-первых, я объявляю некоторые общие функции в интерфейсе My 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>("","")

Я надеюсь, что кто-то здесь знает, как это сделать, потому что это поможет проверке типа этих функций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...