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

duckie

v1.3.0

Published

a simple javascript type checker and assertion library

Downloads

12

Readme

Build Status

duckie

A Javascript type annotation and assertion library with no dependecies. You can make it work anywhere as long as you have es5 shimed your environment.

Install

For node/browserify/webpack user, use npm install.

npm install duckie

For client user, please download the dist file in the build directory.

Example

var duckie = require('duckie');
duckie.array.test([1,2,3]) // true
duckie.array.test('123') // false

duckie.objectOf({
  name: String
}).test({name: 'jack'})  // true

duckie.arrayOf({
  name: String
}).test([{name: 'jack'}]) //true

Example

With duckie, it will ease all of your pain. Defining types is just like defining an object.

function post(data) {
  duckie.ArrayOf({
    name: String,
    age: Number
  }).assert(data); // if data doesn't fit the type, it will throw error
}

Quick Start

Intro

All the type-checker below will contain 2 functions:

  • test will return a boolean to indicate if the val belongs to the type
  • assert will throw an error if the val doesn't belong to the type

For example: duckie.array.test('abcd') will return false, and duckie.array.assert('abcd') will throw an error.

Basic Type

There are 8 basic types for you to directly use, they are:

  • bool
  • string
  • number
  • undefined
  • null
  • array
  • object
  • anything, means any value.

example:

duckie.bool.test(true)  => true
duckie.number.test(123) => true
duckie.array.test([1,2,3]) => true
duckie.array.test('hello') => false

Conditional Type

  • oneOf(Array), any value that is one of the enums.
duckie.OneOf(['a', 'b', 'c']).test('a') // true
duckie.OneOf([1, 2, ,3]).test('a')      // false
  • oneOfType([Type1, Type2..TypeN]), any value that belongs to one of the listed types.
duckie.oneOfType([String, Array]).test('abc') // true
duckie.oneOfType([String, Array]).test([]) // true
duckie.oneOfType([String, Array]).test(123) //false
  • maybe(Type), any value that belongs to the type or exactly equals to undefined or NaN.
duckie.maybe(String).test('abc') //true
duckie.maybe(String).test(null)  // true
duckie.maybe(String).test(undefined) //true
duckie.maybe(String).test(1)   // false

Composite Type

  • arrayOf(Type), any value that is an array and all the items in the array is type Type
duckie.arrayOf(String).test(['abc', 'bcd']) //true
duckie.arrayOf(String).test(['abc', 1])     // false, because there is a number 1 which isn't of type String
duckie.arrayOf(duckie.maybe(String)).test(['abc', null])  //true, it means array can contain string(s) or null/undefined(s)
  • objectOf(/*definition*/), an object that contains the structure described with definition.
duckie.objectOf({name: String}).test({name: 'jack'})   // true
duckie.objectOf({name: String}).test({name: 'jack', age: 18}) // true, because it only check duck type
duckie.objectOf({name: String, gender: String).test({name: 'jack'}) //false, because it not contain gender
// how to describe if a field is optional? use maybe
duckie.objectOf({name: String, age: T.maybe(Number)}).test({name: 'jack'}) // true, because age is optional

Complex Type

How to desribe a data structure that:

  • is an array.
  • each item is a Person
  • the definition of Person is: it has a name as String, age as Number and hobbies as Array of String.

Obviously, we can combine arrayOf and ObjectOf together to achieve the goal.

// first, build an array with person type
duckie.arrayOf(Person)

// second, investigate Person type
duckie.objectOf({
  name: String,
  age:  Number,
  hobbies: duckie.arrayOf(String)
})

// finally, combine them and we get
duckie.arrayOf(duckie.objectOf{
  name: String,
  age:  Number,
  hobbies: duckie.arrayOf(String)
})

Do you find it a little verbose? It looks like we are using something DSL rather than use JS. Why can't we define data structure just as defining data itself? The answer is: Yes, we can.

For arrayOf and objectOf, you don't need to wrap any type checker for inner definitions. It means:

duckie.arrayOf(duckie.objectOf({
  name: String
}))

is just the same as:

duckie.arrayOf({
  name: String
})

so the complex definition of T.arrayOf(Person) can be written as:

duckie.arrayOf({  // omitting the objectOf makes your code cleaner
  name: String,
  age:  Number,
  hobbies: [String]  // you can defined the ArrayOf(String) as [String]
})

Shortcut

For the reason we may want to defined the data structure just like defining the data itself. We can use duckie(Type) to create a type checker. For Example:

duckie([]).test([1,2,3]) // the same as duckie.array.test([1,2,3])
duckie([Number]).test([1,2,3]) // the same as duckie.arrayOf(Number).test([1,2,3])
duckie({name: String}).test({name: 'jack'})  // the same as duckie.objectOf({name: String}).test({name: 'jack'})

CAUTION: duckie([Number, String]) still means duckie.arrayOf(Number) because we tend to think all the items in the array should be the same type and expression duckie([Number, String]) doesn't make any sense.

License

MIT