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

predicates

v2.0.3

Published

Set of various predicates for type checking, assertions, filtering etc

Downloads

57,208

Readme

Predicates

Build Status NPM version Coverage Status

Set of various predicates for type checking, simple assertions, filtering etc.

Features

  • written in typescript (with type guards and function overloading)
  • well defined API design principles
  • predicates description every predicate contains a proper description for easier debugging and automatic assertion generation
  • supports simple type checks with unnecessary verbosity
  • every predicate supports currying if possible

Install

npm install predicates

Full API

Example

const is = require('predicates');

is.string(1); // false
is.string('test'); // true

is.undefinedOr(String, undefined); // true
is.undefinedOr(String, 'string'); // true
is.undefinedOr(is.string, undefined); // true
is.undefinedOr(is.string, 'timmy'); // true
is.undefinedOr(is.string)(undefined); // true
is.undefinedOr(is.string)('timmy'); // true

const isPerson = is.structure({
	name: is.string,
	surname: is.undefinedOr(is.string),
	age: is.number
});

isPerson({name: 'Tom', age: 10}); // true
isPerson({surname: 'Welling', age: 100}); // false, lack of name property
const assertName = is.assert(is.string);
const assertSurname = is.assert(is.notBlank);
const assertAge = is.assert(is.undefinedOr(is.positive));

const Person = function(name, surname, age) {
    assertName(name);
    assertSurname(surname);
    assertAge(age);
}

new Person('Tom', 'Welling', 33); // OK!
new Person('Tom', 'Welling'); // OK!
new Person('Tom', '', 33); // Error: Surname must be a string and cannot be emptye

API design

Generated predicates can be called with more than one argument

Most of type checking, utility libraries force you use predicates with only one argument but predicates doesn.t Additionally predicates preserves the context of function call which allows you to create even more powerful logic.

const is = require('predicates');

const isOkToModifyTags = is.all(
    is.arrayOf(is.string), 
    function(tags, previousTags) {
        // no need to save them again if they are the same as previous ones
        return tags.join(',') !== previousTags.join(',');
    }
);

Module.prototype.modifyTags = function(entityId, tags) {
    var previousTags = getTags(entityId);
    if (isOkToModifyTags(tags, previousTags)) {
        this.saveTags(entityId, tags);
    } else {
        // no need to save them again if they are the same as previous ones
    }
}

Prevents stupid mistakes (fail fast)

Predicates checks whether generated predicate is misconfigured and throws an error as fast as possible.

is.startsWith(''); // Error: Prefix cannot be empty
// since that would be true for all strings

is.in([]); // Error: Collection cannot be empty
// always false

That's why it's a good practice to create predicates at the beginning of a module definition to quickly catch any mistake.

// some module
const is = require('predicates');
const isImage = is.in([]); // Error: Collection cannot be empty

// You don't need to run the whole application to get the error that your predicate is wrong
export class Module {
    
}

Defined and generated predicates will never throw any error

You don't need to check the arguments provided to predicates to make sure they won't cause an error - predicates does it for you.

const isDuck = is.hasProperty('quack');

isDuck(undefined); // false - no error
isDuck(1); // false - no error
isDuck('duck'); // false - no error

is.matches(/.*\.ts/)(100); // false - no error

NOTE! This rule applies only for predicates defined in the library. Any user-defined predicate MAY throw errors (however I don't advise to do so) and predicates will not catch them.

const assertName = is.all(is.string, function(value) {
    if (value === 'admin') {
        throw new Error('Admin is a reserved user name');
    }
});

assertName('admin'); // Error: Admin is a reserved user name

Type guards

Every predicate (if possible) is a type guard

if (is.string(value)) {
   // at this point typescript compiler knows that value is a string 
}

Core types are automatically translated to proper predicate

is.property('foo', is.string)({foo: 'bar'}); // true

// for less verbosity this is possible as well
is.property('foo', String)({foo: 'bar'}); // true
is.arrayOf(String)(['foo']); // true