npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@michaelallenwarner/el-is

v1.1.0

Published

A tiny TypeScript type guard (predicate-function) for narrowing a DOM element by tag-name.

Downloads

16

Readme

el-is

Install

npm install @michaelallenwarner/el-is

Requirements

  • TypeScript >= 5.0 (assuming you're using TypeScript)

Usage

import { elIs } from '@michaelallenwarner/el-is';

const htmlElement = document.querySelector('section'); // `HTMLElement | null`
if (elIs(htmlElement, 'SECTION')) {
  // `htmlElement` now has type `HTMLElement & { tagName: 'SECTION' }`
}

const mathMlElement = document.querySelector('mrow'); // `MathMLElement | null`
if (elIs(mathMlElement, 'mrow')) {
  // `mathMlElement` now has type `MathMLElement & { tagName: 'mrow' }`
}

const element = document.querySelector('.svg-path-element'); // `Element | null`
if (elIs(element, 'path')) {
  // `element` now has type `Element & { tagName: 'path' }`
  /*
    But probably just do `if (element instanceof SVGPathElement)` instead!

    Also, although `Element` will work as a type for the first parameter,
    it's advisable to narrow it first to `HTMLElement`, `MathMLElement`, or `SVGElement`.

    See Usage Notes below.
  */
}

Usage Notes

The elIs() function takes two arguments—a maybe-null DOM element (el) and a string literal (tagName)—and returns the boolean result of a simple el?.tagName === tagName check, but with some TypeScript niceties described below.

But first, a quick warning: you probably should only use this function if the kind of element you're checking against doesn't have its own dedicated interface! For example, if you want to check whether el is a link, I can't think of any reason not to just do if (el instanceof HTMLAnchorElement), so that the type-narrowing gives you all the properties and methods that come with the more specific interface (like HTMLAnchorElement.href). The elIs() function is really for testing whether an element is of a kind that doesn't have its own interface, like <section>.

With that out of the way, here are the TypeScript niceties you get with elIs():

  • When it returns true, the function narrows el's type by ruling out null (if applicable) and intersecting with { tagName: T }, where T is the string-literal type provided as the tagName argument. So if the el you supply has type HTMLElement (or HTMLElement | null), then if elIs(el, 'DIV') returns true, the type of el will be narrowed to HTMLElement & { tagName: 'DIV' }.

  • You get autocomplete functionality and typo-prevention with the tagName parameter.

    Specifically, the tagName parameter must be the value of a standard DOM element's tagName property, and this restriction further depends on the type of the el argument you supply. For example, if el is an instance of HTMLElement, then the supplied tagName argument must be the value of a standard HTML element's tagName property, like 'DIV'. Supported el types are HTMLElement, SVGElement, MathMLElement, the more general Element, and unions of any of these; the tagName argument will always be appropriately restricted. (It's best, though, if el is just HTMLElement, SVGElement, or MathMLElement, so that you don't have to worry about confusing uppercase HTML tag-names like 'A' with lowercase SVG or MathML tag-names like 'a'.)

If you don't use elIs(), you can just do something like if (el.matches('section')) or if (el.tagName === 'section') instead. But then you don't get the type-narrowing, the autocomplete, or the typo-prevention, and you'll probably make the mistake I made in the previous sentence (should be if (el.tagName === 'SECTION')).

A few more notes:

  • Because of the tagName restrictions, this function won't work with custom elements in TypeScript.
  • Although SVGElement is a supported type for the el parameter, it's worth noting that, at the time of writing, every kind of SVG element has its own dedicated interface (like SVGPathElement), so you probably want to reach for instanceof with SVG tags.
  • Deprecated HTML elements are supported (e.g., if el is an HTMLElement, then tagName can be 'MARQUEE').