{"id":15684233,"url":"https://github.com/thk2b/duck-check","last_synced_at":"2025-05-07T15:50:08.575Z","repository":{"id":57216943,"uuid":"111321294","full_name":"thk2b/duck-check","owner":"thk2b","description":"A minimalist runtime type checking utility for duck typing","archived":false,"fork":false,"pushed_at":"2018-02-23T15:50:43.000Z","size":179,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-25T18:21:41.828Z","etag":null,"topics":["duck-typing","javascript","nodejs","object-checker","runtime-typechecking","type-checking"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thk2b.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-19T18:31:45.000Z","updated_at":"2019-07-08T22:03:47.000Z","dependencies_parsed_at":"2022-08-28T21:40:18.886Z","dependency_job_id":null,"html_url":"https://github.com/thk2b/duck-check","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thk2b%2Fduck-check","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thk2b%2Fduck-check/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thk2b%2Fduck-check/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thk2b%2Fduck-check/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thk2b","download_url":"https://codeload.github.com/thk2b/duck-check/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252910611,"owners_count":21823868,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["duck-typing","javascript","nodejs","object-checker","runtime-typechecking","type-checking"],"created_at":"2024-10-03T17:13:17.307Z","updated_at":"2025-05-07T15:50:08.514Z","avatar_url":"https://github.com/thk2b.png","language":"JavaScript","readme":"## duck-check\n\n🦆 A minimalist runtime type checking utility.\n\n[![npm version](https://badge.fury.io/js/duck-check.svg)](https://badge.fury.io/js/duck-check)\n[![Open Source Love](https://badges.frapsoft.com/os/mit/mit.svg?v=102)](https://github.com/ellerbrock/open-source-badge/)\n\n## New in v2.0.0\n- Remove Error batching to improve efficiency.\n- Remove complex error messages thrown by `assert` to improve efficiency.\n\n## Usage:\n### Installation\n`duck-check` is a Javascript package published in the NPM registry. Install by running\n```\nnpm install --save duck-check\n```\n\n### Quick Start\n\n*([skip to guide](#guide))*\n\n**Getting started**\n\n```js\nconst { \n assert, \n is, \n check, \n not, \n one_of, oneOf,\n either, \n any \n} = require('duck-check')\n```\n\n**Basic checks**\n\n```js\ncheck(Number)(1) // -\u003e true\ncheck(Number)(\"i'm not a number\") // -\u003e TypeError\n\nassert(String)('hello world!') // -\u003e true\nassert(String)(42) // -\u003e false\n\nis(String)('hello world!')// -\u003e true\nis(String)(42)// -\u003e false\n\nis(Date)(new Date()) // -\u003e true\nis(Date)('today') // -\u003e false\n\nis(Function)(() =\u003e \"i'm a function\") // -\u003e true\n\nconst even = n =\u003e n % 2 === 0\nis(even)(20) // -\u003e true\nis(even)(3) // -\u003e false\n```\n\n**[Typed Arrays](#typed-arrays)**\n\n```js\nis([ Number ])([1,2,3]) // -\u003e true\nis([ Number ])([1,'2',3]) // -\u003e false\nis([ Number ])([]) // -\u003e false\nis([ Number ])(1) // -\u003e false\n```\n\n**[Positional Arrays](#positional-arrays)**\n\n```js\nis([ Number, String, Boolean ])([1,'a', true]) // -\u003e true\nis([ Number, String, Boolean ])([1,false, 'a']) // -\u003e false\n```\n\n**[Objects](#objects)**\n\n```js\nis( { key: String } )( { key: 'value '} ) // -\u003e true\nis( { key: String } )( { key: 42 } ) // -\u003e false\nis( { key: String } )( { wrong: 'value' } ) // -\u003e false\nis( { key: String } )( { key: 'value', other: 42 } ) // -\u003e true\n```\n\n**[Reusing previous checker functions](#functions)**\n\n```js\nconst Person = assert({ name: String, age: Number })\nassert([ Person ])([ { name: 'John', age: 45 }, { name: 'Jane', age: 55 } ]) // -\u003e true\n```\n\n**[Mixed Objects and Arrays](#midxed-objects-and-arrays)**\n\n```js\nis( [ { key: String } ] )( [ { key: 'first' }, { key: 'second' } ] ) // -\u003e true\nis( [ { key: String } ] )( [ { key: 'first' }, { wrong: 'second' } ] ) // -\u003e false\n```\n\n**[Modifiers](#modifiers)**\n\n```js\nnot(Number)(null) // -\u003e true\nnot(Number)(1) // -\u003e false\ncheck(not(Number))(1) // -\u003e TypeError\n\none_of(Number, String, null)(1) // -\u003e true\none_of(Number, String, null)('a') // -\u003e true\none_of(Number, String, null)(null) // -\u003e true\none_of(Number, String, null)(NaN) // -\u003e false\n\neither([ Number ], { x: Number, y: Number } )( [ 1, 2 ] ) // -\u003e true\neither([ Number ], { x: Number, y: Number } )( { x: 1, y: 2 } ) // -\u003e true\neither([ Number ], { x: Number, y: Number } )( { x: 1, wrong: 2 } ) // -\u003e false\n\nis({ x: any })({ x: 1 }) // -\u003e true\nis({ x: any })({ x: NaN }) // -\u003e true\nis({ x: any })({ wrong: 1 }) // -\u003e false\nis({ x: either(Number, String)})({x: 1}) // -\u003e true\nis({ x: either(Number, String)})({x: false}) // -\u003e false\n```\n\n### Guide\n#### Importing:\n\nIn Node:\n```js\nconst { check, assert, is, modifiers, not, one_of, oneOf, any, either } = require('duck-check')\n```\n\nES6 modules:\n\n```js\nimport { check, assert, is, modifiers, not, one_of, oneOf, any, either } from 'duck-check'\n```\n\n#### Schema\n\nA schema represents the expected structure or type of your data. It is passed as an argument to the `check`, `assert` and other modifier functions. \n\nA valid schema is: \n- A primitive type constructor such as `Number`, `String`, `Boolean`, `Function`\n- A primitive object, such as `null`, `undefined`, `NaN`\n- Any class constructor\n- An array litteral containing any valid schema (interpreted as a [typed array](typed-arays))\n- An array litteral containing multiple valid schemas (interpreted as a [positional array](positional-arays))\n- An object litteral with a key and any valid schema as a value\n- A function\n\n#### Main API\n\n**`check(schema)(data)`**\n\nReturns a function that takes data as its argument, and throws a `TypeError` if the data does not match the schema. Returns `undefined` otherwise.\n\n**`is(schema)(data)`**\n\nAlias for `assert`\n\n**`assert(schema)(data)`**\n\nReturns a function that takes data as its argument, and returns `false` if the data does not match the schema. Returns `true` otherwise.\n\n#### Checking data\n\n##### Typed Arrays\n\nA typed array is an array where all elements are of one type. For instance, an array of numbers is a typed array.\n\n```js\nis([ Number ])( [1,2,3] )\n```\n\n##### Positional Arrays\n\nA positional array is an array where each position in the array is of a specific type. For instance, an array with a first number, then a string.\n\n```js\nis([ Number, String ])( [1, 'a'] )\n```\n\n##### Objects\n\nAn object has keys and values. For instance, an object with a key of `key` and a value of type `String`.\n\n```js\nis({ key: String })( {key: 'value' })\n```\n\nThe test passes if all keys declared in the schema object are defined in the data, and if the value of each key matches the type declared in the schema. Keys declared in the data but not in the schema are ignored. \n\nTo check for a key with any value, use the `any` [modifier](#modifiers). \n\n##### Mixed Objects and Arrays\n\nSince any schema can contain other schemas, you can check for arrays of objects, objects containing arrays, etc... You can compose your schemas as needed without limit (as long as they are not recursive).\n\n##### Functions\n\nIf you pass a function in the schema, it will be called with the data as its argument. If the function returns `true`, the test passes. if it returns `false`, or throws an error, the test fails. \n\nThis means previous calls to `check` or `assert` can be used in any schema.\n\n```js\nconst Person = assert({ name: String, age: Number }) // ! \\\\ Do not use this naming convention in project involving OOP classes!\nassert([ Person ])([ { name: 'John', age: 45 }, { name: 'Jane', age: 55 } ]) // -\u003e true\n```\n\nYou can also define your own functions as needed. \n\n```js\nconst even = n =\u003e n % 2 === 0\nis([even])([20, 22]) // -\u003e true\nis([even])([20, 21]) // -\u003e false\n```\n\n##### Modifiers\n\nModifiers take a schema, and alter the result of the check.\n\nA modifier can be used anywhere in a schema, or even with other modifiers. For instance, you can declare an array of neither numbers nor strings. \n\n```js\nis([ not(either(Number, String)) ])([1, 'a']) // -\u003e false\n```\n\n**`any(data)`**\n\nA function that always returns true. Do not call the function when declaring the schema.\n\n```js\nis(any)() // -\u003e true\n```\n\n**`not(schema)`**\n\nReturns a function that takes in data and returns the negation of `check(schema)(data)`. \n\n```js\nnot(Number)(null) // -\u003e true\nnot(Number)(1) // -\u003e false\ncheck(not(Number))(1) // -\u003e TypeError\n```\n\n**`either(schema_a, schema_b)`**\n\nReturns a function that takes in data and returns `true` if either schemas match the data. \n\n```js\neither([ Number ], { x: Number, y: Number } )( [ 1, 2 ] ) // -\u003e true\neither([ Number ], { x: Number, y: Number } )( { x: 1, y: 2 } ) // -\u003e true\neither([ Number ], { x: Number, y: Number } )( { x: 1, wrong: 2 } ) // -\u003e false\n```\n\n**`oneOf(...args)`**\n\nalias of `one_of`\n\n**`one_of(...args)`**\n\nReturns a function that takes in data and returns `true` if one of the schemas passed as arguments match the data. \n\n```js\none_of(Number, String, null)(1) // -\u003e true\none_of(Number, String, null)('a') // -\u003e true\none_of(Number, String, null)(null) // -\u003e true\none_of(Number, String, null)(NaN) // -\u003e false\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthk2b%2Fduck-check","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthk2b%2Fduck-check","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthk2b%2Fduck-check/lists"}