[![Coverage Status](https://codecov.io/gh/sindresorhus/ow/branch/main/graph/badge.svg)](https://codecov.io/gh/sindresorhus/ow) [![gzip size](https://badgen.net/bundlephobia/minzip/ow)](https://bundlephobia.com/result?p=ow) [![install size](https://packagephobia.now.sh/badge?p=ow)](https://packagephobia.now.sh/result?p=ow) > Function argument validation for humans ## Highlights - Expressive chainable API - Lots of built-in validations - Supports custom validations - Automatic label inference in Node.js - Written in TypeScript ## Install ``` $ npm install ow ``` ## Usage *If you use CommonJS, you need to import is as `const {default: ow} = require('ow')`.* ```ts import ow from 'ow'; const unicorn = input => { ow(input, ow.string.minLength(5)); // … }; unicorn(3); //=> ArgumentError: Expected `input` to be of type `string` but received type `number` unicorn('yo'); //=> ArgumentError: Expected string `input` to have a minimum length of `5`, got `yo` ``` We can also match the shape of an object. ```ts import ow from 'ow'; const unicorn = { rainbow: '🌈', stars: { value: '🌟' } }; ow(unicorn, ow.object.exactShape({ rainbow: ow.string, stars: { value: ow.number } })); //=> ArgumentError: Expected property `stars.value` to be of type `number` but received type `string` in object `unicorn` ``` ***Note:*** If you intend on using `ow` for development purposes only, use `require('ow/dev-only')` instead of the usual `import 'ow'`, and run the bundler with `NODE_ENV` set to `production` (e.g. `$ NODE_ENV="production" parcel build index.js`). This will make `ow` automatically export a shim when running in production, which should result in a significantly lower bundle size. ## API [Complete API documentation](https://sindresorhus.com/ow/interfaces/ow.html) Ow includes TypeScript type guards, so using it will narrow the type of previously-unknown values. ```ts function (input: unknown) { input.slice(0, 3) // Error, Property 'slice' does not exist on type 'unknown' ow(input, ow.string) input.slice(0, 3) // OK } ``` ### ow(value, predicate) Test if `value` matches the provided `predicate`. Throws an `ArgumentError` if the test fails. ### ow(value, label, predicate) Test if `value` matches the provided `predicate`. Throws an `ArgumentError` with the specified `label` if the test fails. The `label` is automatically inferred in Node.js but you can override it by passing in a value for `label`. The automatic label inference doesn't work in the browser. ### ow.isValid(value, predicate) Returns `true` if the value matches the predicate, otherwise returns `false`. ### ow.create(predicate) Create a reusable validator. ```ts const checkPassword = ow.create(ow.string.minLength(6)); const password = 'foo'; checkPassword(password); //=> ArgumentError: Expected string `password` to have a minimum length of `6`, got `foo` ``` ### ow.create(label, predicate) Create a reusable validator with a specific `label`. ```ts const checkPassword = ow.create('password', ow.string.minLength(6)); checkPassword('foo'); //=> ArgumentError: Expected string `password` to have a minimum length of `6`, got `foo` ``` ### ow.any(...predicate[]) Returns a predicate that verifies if the value matches at least one of the given predicates. ```ts ow('foo', ow.any(ow.string.maxLength(3), ow.number)); ``` ### ow.optional.{type} Makes the predicate optional. An optional predicate means that it doesn't fail if the value is `undefined`. ```ts ow(1, ow.optional.number); ow(undefined, ow.optional.number); ``` ### ow.{type} All the below types return a predicate. Every predicate has some extra operators that you can use to test the value even more fine-grained. #### Primitives - [`undefined`](https://sindresorhus.com/ow/interfaces/ow.html#undefined-1) - [`null`](https://sindresorhus.com/ow/interfaces/ow.html#null) - [`string`](https://sindresorhus.com/ow/classes/stringpredicate.html) - [`number`](https://sindresorhus.com/ow/classes/numberpredicate.html) - [`boolean`](https://sindresorhus.com/ow/classes/booleanpredicate.html) - [`symbol`](https://sindresorhus.com/ow/interfaces/ow.html#symbol-1) #### Built-in types - [`array`](https://sindresorhus.com/ow/classes/arraypredicate.html) - [`function`](https://sindresorhus.com/ow/interfaces/ow.html#function) - [`buffer`](https://sindresorhus.com/ow/interfaces/ow.html#buffer) - [`object`](https://sindresorhus.com/ow/classes/objectpredicate.html) - [`regExp`](https://sindresorhus.com/ow/interfaces/ow.html#regexp-1) - [`date`](https://sindresorhus.com/ow/classes/datepredicate.html) - [`error`](https://sindresorhus.com/ow/classes/errorpredicate.html) - [`promise`](https://sindresorhus.com/ow/interfaces/ow.html#promise-1) - [`map`](https://sindresorhus.com/ow/classes/mappredicate.html) - [`set`](https://sindresorhus.com/ow/classes/setpredicate.html) - [`weakMap`](https://sindresorhus.com/ow/classes/weakmappredicate.html) - [`weakSet`](https://sindresorhus.com/ow/classes/weaksetpredicate.html) #### Typed arrays - [`int8Array`](https://sindresorhus.com/ow/interfaces/ow.html#int8Array) - [`uint8Array`](https://sindresorhus.com/ow/interfaces/ow.html#uint8Array-1) - [`uint8ClampedArray`](https://sindresorhus.com/ow/interfaces/ow.html#uint8ClampedArray-1) - [`int16Array`](https://sindresorhus.com/ow/interfaces/ow.html#int16Array) - [`uint16Array`](https://sindresorhus.com/ow/interfaces/ow.html#uint16Array-1) - [`int32Array`](https://sindresorhus.com/ow/interfaces/ow.html#in32Array) - [`uint32Array`](https://sindresorhus.com/ow/interfaces/ow.html#uin32Array-1) - [`float32Array`](https://sindresorhus.com/ow/interfaces/ow.html#float32Array) - [`float64Array`](https://sindresorhus.com/ow/interfaces/ow.html#float64Array) #### Structured data - [`arrayBuffer`](https://sindresorhus.com/ow/interfaces/ow.html#arraybuffer) - [`dataView`](https://sindresorhus.com/ow/interfaces/ow.html#dataview) - [`sharedArrayBuffer`](https://sindresorhus.com/ow/interfaces/ow.html#sharedarraybuffer-1) #### Miscellaneous - [`nan`](https://sindresorhus.com/ow/interfaces/ow.html#nan) - [`nullOrUndefined`](https://sindresorhus.com/ow/interfaces/ow.html#nullorundefined) - [`iterable`](https://sindresorhus.com/ow/interfaces/ow.html#iterable) - [`typedArray`](https://sindresorhus.com/ow/interfaces/ow.html#typedarray-1) ### Predicates The following predicates are available on every type. #### not Inverts the following predicate. ```ts ow(1, ow.number.not.infinite); ow('', ow.string.not.empty); //=> ArgumentError: Expected string to not be empty, got `` ``` #### is(fn) Use a custom validation function. Return `true` if the value matches the validation, return `false` if it doesn't. ```ts ow(1, ow.number.is(x => x < 10)); ow(1, ow.number.is(x => x > 10)); //=> ArgumentError: Expected `1` to pass custom validation function ``` Instead of returning `false`, you can also return a custom error message which results in a failure. ```ts const greaterThan = (max: number, x: number) => { return x > max || `Expected \`${x}\` to be greater than \`${max}\``; }; ow(5, ow.number.is(x => greaterThan(10, x))); //=> ArgumentError: Expected `5` to be greater than `10` ``` #### validate(fn) Use a custom validation object. The difference with `is` is that the function should return a validation object, which allows more flexibility. ```ts ow(1, ow.number.validate(value => ({ validator: value > 10, message: `Expected value to be greater than 10, got ${value}` }))); //=> ArgumentError: (number) Expected value to be greater than 10, got 1 ``` You can also pass in a function as `message` value which accepts the label as argument. ```ts ow(1, 'input', ow.number.validate(value => ({ validator: value > 10, message: label => `Expected ${label} to be greater than 10, got ${value}` }))); //=> ArgumentError: Expected number `input` to be greater than 10, got 1 ``` #### message(string | fn) Provide a custom message: ```ts ow('🌈', 'unicorn', ow.string.equals('🦄').message('Expected unicorn, got rainbow')); //=> ArgumentError: Expected unicorn, got rainbow ``` You can also pass in a function which receives the value as the first parameter and the label as the second parameter and is expected to return the message. ```ts ow('🌈', ow.string.minLength(5).message((value, label) => `Expected ${label}, to have a minimum length of 5, got \`${value}\``)); //=> ArgumentError: Expected string, to be have a minimum length of 5, got `🌈` ``` It's also possible to add a separate message per validation: ```ts ow( '1234', ow.string .minLength(5).message((value, label) => `Expected ${label}, to be have a minimum length of 5, got \`${value}\``) .url.message('This is no url') ); //=> ArgumentError: Expected string, to be have a minimum length of 5, got `1234` ow( '12345', ow.string .minLength(5).message((value, label) => `Expected ${label}, to be have a minimum length of 5, got \`${value}\``) .url.message('This is no url') ); //=> ArgumentError: This is no url ``` This can be useful for creating your own reusable validators which can be extracted to a separate npm package. ## Maintainers - [Sindre Sorhus](https://github.com/sindresorhus) - [Sam Verschueren](https://github.com/SamVerschueren) ## Related - [@sindresorhus/is](https://github.com/sindresorhus/is) - Type check values - [ngx-ow](https://github.com/SamVerschueren/ngx-ow) - Angular form validation on steroids