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

type-of-data

v1.1.0

Published

Reliable dynamic type checking

Downloads

168

Readme

NPM Version NPM Downloads GitHub issues Telegram

Dynamic type checking

Static type checking does not work in all situations, especially when dealing with data from unknown or untrusted sources. In those cases the application must resort to dynamic type checking at run-time.

Check data types at runtime

For example:

typeOf([
  {selector, is: String},
  {regExp, is: RegExp},
  {returnAll, is: Boolean}
]);

or

typeOf({str, is: String});

You can use these types:

  • 'global' - global object
  • 'process' - NodeJS process
  • null - null value
  • 'null' - null value
  • Boolean - primitive booleans and instances of Boolean
  • 'boolean' - primitive booleans only
  • 'Boolean' - instances of Boolean only
  • String - primitive strings and instances of String
  • 'string' - primitive strings only
  • 'String' - instances of String only
  • 'String Iterator' - String iterator
  • Number - instances of Number only
  • 'number' - primitive numbers only
  • 'Number' - instances of Number only
  • Symbol - symbols (they are primitives)
  • Object - any objects which toString tag is Object
  • Function - any function (AsyncFunction and GeneratorFunction)
  • 'AsyncFunction' - async functions
  • 'GeneratorFunction' - generator functions
  • JSON - any valid json string
  • Array - any objects which toString tag is Array
  • 'Array Iterator' - array iterator (for example, [].keys())
  • RegExp
  • Date
  • Promise
  • Map
  • 'Map Iterator'
  • WeakMap
  • Set
  • 'Set Iterator'
  • WeakSet
  • Error
  • DataView
  • Float32Array
  • Uint8Array
  • ...
  • Classes and constructors
  • [Symbol.toStringTag]
  • toString tag

Do not use 'undefined' type, use 'optional' or 'opt' key.

Use destructuring assignment to unpack properties from objects into distinct variables.

The function returns an object with all the variables.

Installation

npm i type-of-data

Usage

const typeOf = require('type-of-data');

function fn (selector, regExp, returnAll = true) {
  // Throw a TypeError if type is not correct
  typeOf([
    {selector, is: String},
    {regExp, is: RegExp},
    {returnAll, is: Boolean}
  ]);
  /* Here you can be sure that the types a correct... */
}

More examples:

// Single definition
typeOf({regExp, is: RegExp});

// Array of definitions
typeOf([
  {str, is: String}, // Any string
  {str, is: 'string'}, // Primitive string only
  {num: 22, is: Number},
  {variable, is: [null, Object, String]}, // Null type
  {param, is: [Object, Array], optional: true}, // Can be undefined
  {x, is: ['string', 'number', Array]} // Primitive types only
]);

Tests:

describe('typeOf:', () => {
  it('multiple definitions', () => {
    const Noop = function () {};
    const globalObject = typeof window !== 'undefined' ? window : (typeof global !== 'undefined' ? global : self);

    const fn = () => typeOf([
      {variable: globalObject, is: 'global'},

      {variable: true, is: Boolean},
      {variable: false, is: Boolean},
      {variable: new Boolean([1,2]), is: Boolean},
      {variable: new Boolean(''), is: Boolean},
      {variable: new Boolean(''), is: 'Boolean'},

      {variable: true, is: 'boolean'},
      {variable: false, is: 'boolean'},

      {variable: -1, is: Number},
      {variable: 0, is: Number},
      {variable: -0, is: Number},
      {variable: +0, is: Number},
      {variable: 1, is: Number},
      {variable: +1, is: Number},
      {variable: new Number(1), is: Number},
      {variable: new Number(''), is: Number},
      {variable: new Number(0), is: 'Number'},

      {variable: 0, is: 'number'},
      {variable: 2.456, is: 'number'},
      {variable: -100, is: 'number'},
      {variable: NaN, is: 'number'}, // Is primitive number
      {variable: Infinity, is: 'number'}, // Is primitive number
      {variable: +Infinity, is: 'number'},
      {variable: -Infinity, is: 'number'},

      {variable: '', is: String},
      {variable: 'gsd', is: String},
      {variable: ('gsd')[Symbol.iterator](), is: 'String Iterator'},
      {variable: String(''), is: String},
      {variable: new String(1), is: String},
      {variable: new String(false), is: 'String'},

      {variable: String(''), is: 'string'},
      {variable: String('test'), is: 'string'},
      {variable: '', is: 'string'},
      {variable: 'test', is: 'string'},

      {variable: Symbol('fsd'), is: Symbol},
      {variable: Symbol(), is: 'symbol'},
      {variable: Symbol('fsd'), is: 'symbol'},

      {variable: [], is: Array},
      {variable: [1,2,3], is: 'Array'},
      {variable: new Array(10), is: Array},
      {variable: [].keys(), is: 'Array Iterator'},

      {variable: {}, is: Object},
      {variable: {x: 2}, is: 'Object'},
      {variable: new Object({a: 2}), is: Object},
      {variable: new (function Noop () {}), is: Object},
      {variable: new Noop, is: Noop},
      {variable: new Noop, is: 'Object'},
      {variable: new Noop, is: Object},
      {variable: new (function () {}), is: Object},

      {variable: function () {}, is: Function},
      {variable: function named () {}, is: Function},
      {variable: function named () {}, is: 'Function'},
      {variable: () => {}, is: Function},
      {variable: async function () {}, is: Function},
      {variable: async () => {}, is: Function},
      {variable: function* gen () {}, is: Function},
      {variable: async () => {}, is: 'AsyncFunction'},
      {variable: function* gen () {}, is: 'GeneratorFunction'},

      {variable: new Date(), is: Date},
      {variable: new Date(), is: 'Date'},

      {variable: /\d+/, is: RegExp},
      {variable: new RegExp('\d+'), is: RegExp},
      {variable: new RegExp('\d+'), is: 'RegExp'},

      {variable: new Promise(() => {}), is: Promise},
      {variable: Promise.resolve(), is: Promise},
      {variable: Promise.reject(), is: Promise},
      {variable: Promise.reject(), is: 'Promise'},

      {variable: new Map(), is: Map},
      {variable: new Map(), is: 'Map'},
      {variable: (new Map()).values(), is: 'Map Iterator'},
      {variable: new Set(), is: Set},
      {variable: new Set(), is: 'Set'},
      {variable: (new Set()).values(), is: 'Set Iterator'},
      {variable: new WeakMap(), is: WeakMap},
      {variable: new WeakMap(), is: 'WeakMap'},
      {variable: new WeakSet(), is: WeakSet},
      {variable: new WeakSet(), is: 'WeakSet'}
    ]);

    expect(fn).not.to.throw();
  });
});

Throws TypeError:

describe('typeOf:', () => {
  it('single definition throws', () => {
    const fns = [
      () => typeOf({variable: new Boolean({}), is: 'boolean'}), // Not primitive
      () => typeOf({variable: false, is: 'Boolean'}), // Not object
      () => typeOf({variable: new String('test'), is: 'string'}),
      () => typeOf({variable: 'test-string', is: 'String'}),
      () => typeOf({variable: new Number(214), is: 'number'}),
      () => typeOf({variable: Infinity, is: Number}), // Not a valid number
      () => typeOf({variable: NaN, is: Number}), // Not a valid number
      () => typeOf({variable: 124214, is: String}), // Not a string
      () => typeOf({variable: true, is: [Array, String]}), // Not found
      () => typeOf({variable: undefined, is: [Array, null]}), // Not optional
      () => typeOf({variable: undefined, is: Object}),
      () => typeOf({variable: undefined, is: null})
    ];

    for (const fn of fns) {
      expect(fn).to.throw(TypeError);
    }
  });
});

Tip

You can find more examples in tests.