Giter Site home page Giter Site logo

predicates's Introduction

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

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 to use predicates with only one argument but predicates doesn't. Additionally, predicates preserves the context of function calls 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 a 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 mistakes.

// 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

predicates's People

Contributors

masterodin avatar offirmo avatar wookieb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

jkso

predicates's Issues

Create "prop" helper function to make filtering by property easier

With prop function we can do something like this

var tab = [{id: 1, name: 'Thomas', yearOfBirth: 1980}, {id:2, name: 'Jerry', yearOfBirth: 1990}];
tab.filter(is.prop('yearOfBirth', is.greaterThan(1990)));  // [{id:2, name: 'Jerry', yearOfBirth: 1990}]|

Also consider whether it should allow to use complex paths like 'obj.prop1.data'.

Remove overzealous type guards

if(is.emptyArray(arr)) {
 return [];
}

arr.map(); // this will fail as typescript detects that it's impossible to execute this line

Bower support

This lib looks nice !

However, I'm writing dual-stack code and would be happy to have 1st class browser compatibility.

If you have time...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.