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

ts-type-guards

v0.7.0

Published

Curried TypeScript type guards for primitive types and classes

Downloads

19,462

Readme

ts-type-guards

Curried TypeScript type guards for primitive types and classes

NPM Version Downloads Stats

Simplifies typechecking by providing type guards to check if something is of a certain type or of the same type as something else. Includes tailor-made type guards for the primitive types and a general one for "classy" types.

Installation

npm install ts-type-guards --save

Usage Examples

Basic Usage

import { is } from "ts-type-guards";

const header = document.querySelector("header");
console.log(header.textContent); // Error: Object is possibly 'null'.
if (is(HTMLElement)(header)) {
    console.log(header.textContent); // Compiles and runs safely.
}

Because is, only etc are curried, you can use them like so:

import { is } from "ts-type-guards";

const foos = Array.from(document.querySelectorAll(".foo"));
const fooImages = foos.filter(is(HTMLImageElement));
const srcs = fooImages.map(img => img.src); // Compiles and runs safely.

Equivalent:

import { only } from "ts-type-guards";

const foos = Array.from(document.querySelectorAll(".foo"));
const fooImages = only(HTMLImageElement)(foos);
const srcs = fooImages.map(img => img.src); // Compiles and runs safely.

Checking Against Another Value

Use isLike to check if something is of the same type as a reference value:

import { isLike } from "ts-type-guards";

// We want to make sure that this function always returns a T:
function getFromLocalStorage<T>(key: string, fallback: T): T {
    const saved: string | null = localStorage.getItem(key);
    if (isNull(saved)) {
        return fallback;
    }
    const parsed: any = JSON.parse(saved);
    return (
        isLike(fallback)(parsed)
        ? parsed // parsed is like fallback, so it is a T!
        : fallback // parsed has wrong type, so return fallback.
    );
}

getFromLocalStorage("volume", 50); // Guaranteed to be a number.

(Note that this function can still throw DOMException or SyntaxError, but that's not a typechecking problem.)

Subclasses

is is basically a partially applicable instanceof. For classy types, isLike(ref)(x) is equivalent to x instanceof ref.constructor.

class Animal {}
class Lion extends Animal {}
class Warthog extends Animal {}

const someone = new Animal();
const simba = new Lion();
const nala = new Lion();
const pumbaa = new Warthog();

is(Animal)(simba);  // true
is(Lion)(simba);    // true
is(Warthog)(simba); // false
is(Lion)(someone);  // false

isLike(someone)(simba); // true
isLike(nala)(simba);    // true
isLike(pumbaa)(simba);  // false
isLike(nala)(someone);  // false

Primitive Types

is can only handle classy types, so the primitive ones have their own type guards:

isUndefined(undefined); // true
isNumber("5"); // false

isLike supports the primitive types as well:

isLike(5)(1.0); // true (because all numbers are floating point in JS)
isLike(null)(undefined); // false

The non-primitive types Boolean, Number and String share some, but not all, semantics with the primitive types boolean, number and string, respectively. The main difference lies in their equality semantics:

           "foo"  ===            "foo" ; // true
new String("foo") === new String("foo"); // false

ts-type-guards includes type guards for the cases when you don't care whether a value is of a primitive type or its pseudo-primitive counterpart. For example, to check if a value is either a string or a String, use isStringLike.

Reusing Type Guards

Although it may seem clunky to have to write is(x)(y) instead of is(x, y), this is a design choice based on the fact that partial application is so awesome. Not only does it get rid of xs.filter(x => is(T, x)) in favor of xs.filter(is(T)), it also lets you save and reuse type guards:

const isFoo = is(LongModuleName.Foo);

if (isFoo(x)) {
    x.baz();
}

xs.filter(isFoo).forEach(x => x.baz());

Arrays

You can check if something is an array of a certain type:

isArrayOfNumbers([1, 2, 3]); // true
isArrayOfNumbers([1, 2, "3"]); // false
isArrayOf(Error)([
    new RangeError(),
    new TypeError(),
]); // true

Contributing

  1. Fork the repo.
  2. Create your feature branch (git checkout -b feature/foobar).
  3. Examine and add your changes (git diff, then git add ...).
  4. Commit your changes (git commit -m 'Add some foobar').
  5. Push your feature branch (git push origin feature/foobar).
  6. Create a pull request.

License

MIT