Skip to content

Suggestion: introduce UniveralElement to eliminate most type assertions in DOM programming (prototype created) #3304

Closed
@duanyao

Description

@duanyao

TS heavily relies on type assertion in DOM programming. In my experiences, type assertion is a major factor of produtivity-reduction in font-end TS. There is another user expressed similar concern (#3263).

So I try to eliminate most type assertions in DOM programming by adding a UniveralElement interface to lib.d.ts, see my fork of lib.es6.d.ts.

In my fork, querySelector(), getElementById(), getElementsByClassName(), children, firstElementChild etc. return UniversalElement or a list of UniversalElement, which inherits all known sub interfaces of Element; UIEvent::target is typed as UniversalUIEventTarget, which extends UniversalElement, Document, and Window. So in most case so you don't have to cast the result before use anymore. Additionally you don't loose the power of type check and autocompletion.

A snapshot of autocompletion using my prototype:

And some sample codes:

/// <reference path="lib.es6.d.ts" />

var ue = document.querySelector('#foo'); // UniversalElement
// from Element
var cls: string = ue.className;
// from HTMLElement
ue.blur();
// from HTMLMediaElement
ue.play();

// from HTMLInputElement
var files = document.querySelectorAll('input[type=file]')[0].files;
var fname = files[0].name;

// from HTMLImageElement
var nh = document.body.children[0].naturalHeight;

var svg = document.getElementsByClassName("bar")[0];
// from SVGElement
var vp = svg.viewportElement;
// from SVGLineElement
svg.x1.baseVal.newValueSpecifiedUnits(1, SVGLength.SVG_LENGTHTYPE_PX);

// type of href from HTMLAnchorElement becomes "any" because of type confliction
// with SVGElements
var href = document.querySelector('a').href;

// UIEvent::target is UniversalUIEventTarget, which extends UniversalElement,
// Document, and Window
document.addEventListener('mousemove', ev => {
    var targ = ev.target;
    if (targ.classList.contains('movable')) {
        targ.style.left = ev.pageX + 'px';
        targ.style.right = ev.pageX + 'px';
    }
});

@NekR and @kitsonk, what do you think?

Metadata

Metadata

Assignees

No one assigned

    Labels

    DeclinedThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions