Provides runtime type checking for JavaScript function parameters similar to TypeScript, but with no compiling or dependencies.
- Zero dependencies
- TypeScript-like parameter validation in pure JavaScript
- Named, single, and positional parameter support
- Coercion options for numbers and booleans
- Regular Expression validation for strings
- Custom type support
- Extra parameter warnings
- Optional return type validation
- Easy to integrate with intuitive syntax
- Supports async / Promsie chaining
- Full test suite included
Install via npm.
npm i validated-methodOr import from CDN.
import { ValidatedMethod } from 'https://unpkg.com/validated-method/validated-method.js';Or copy validated-method.js into your project.
import { ValidatedMethod } from 'validated-method';
class UserService {
createUser = new ValidatedMethod({
username: 'string',
age: 'number',
active: 'boolean',
roles: 'array',
settings: 'object',
email: /^[^@]+@[^@]+\.[^@]+$/,
birthday: ['string', 'optional']
title: 'string'
}, async opts => {
// Parameters are validated, safe to use
return await db.users.create(opts);
});
}
const myService = new UserService();
myService.createUser({
username: 'besworks',
age: 40,
active: true,
roles: [ 'admin', 'wizard' ],
settings: { darkmode: 'auto' },
email: 'example@domain.tld',
// birthday: is optional so undefined is ok
// Throw TypeError because title: is undefined
});'string'- String values'boolean'- Truthy/Falsey values (coerced usingBoolean())'object'- Object literals'array'- Arrays of any length including 0'function'- Executable functions'null'- Empty values
'int'- Integers with truncating coercion (usesparseInt())'roundint'- Integers with rounding coercion (usesMath.round())'strictint'- Integers without coercion'number'- Alias of'float''float'- Floating point numbers with coercion (usesparseFloat())'strictfloat'- Floating point numbers without coercion
'any'- Any value includingnull, exceptundefined'undefined'- Alias of'optional''optional'- Value can beundefined'strictboolean'- Booleans only without coercion/^test$/ig- Regular Expression literal (without quotes, usestoString())ClassName- Class comparison (usinginstanceof)(a) => a === b- any declared or incline function can be used as a validator
The _$ helper is provided for convenience but can be renamed on import if it conflicts with other libraries:
import { _$ as VM } from 'validated-method';
const getData = VM('string', performLookupByName);class Widget {
node = document.getElementById('widget')
?? document.createElement('custom-widget');
}
const configureWidget = _$({
widget: Widget,
className: 'string'
}, opts => {
opts.widget.node.classList.add(opts.className);
// safe to call classList because we know
// opts.widget.node is an HTMLElement
// and opts.className is a string
});
configureWidget(new Widget(), 'green');By default, ValidatedMethod warns about unexpected parameters:
const addRecord = _$({
name: 'string',
age: 'number'
}, insertData);
addRecord({
name: 'test',
age: 40,
extra: true // Warning: "Unexpected parameter: extra"
});You can globally supress warnings with the static quiet flag.
ValidatedMethod.quiet = true;
const getData = _$({
bleep: 'boolean',
bloop: 'array'
}, opts => {
return {
e: opts.bleep,
o: opts.bloop
}
});
const ref = {
bleep: true,
bloop: [],
derp: { ...bigObj },
zzz: 'more'
};
getData(ref); // no warnings, best for productionconst method = _$(
{ name: 'string', age: 'number' },
opts => `${opts.name} is ${opts.age}`
);
method({ name: 'Test', age: 42 });// Using type identifier
const $ = _$('string', query =>
document.querySelector(query)
);
$('.my-element');
// Using Custom class
const process = _$(
CustomType, instance => instance.process()
);const add = _$(
['number', 'number'], (a, b) => a + b
);
add(40, 2); // Returns 42
const delayed = _$(
['int', 'function'], (ms, callback) => setTimeout(callback, ms)
);
delayed(1000, () => console.log('Done!')); For functions that take no parameters, you can use any of these equivalent forms:
// These all create a parameterless function that returns a number
const fn1 = _$(undefined, () => 42, 'number');
const fn2 = _$(null, () => 42, 'number');
const fn3 = _$('void', () => 42, 'number');
const fn4 = _$([], () => 42, 'number');
const result = fn1(); // Returns 42
fn1(42); // Throws: Expected 0 arguments, got 1You can use functions as input type validators. They must be synchronous and return a truthy/falsey value.
const isEven = n => n % 2 === 0;
const getHalf = _$(isEven, num => num/2);
getHalf(42); // Accepted input
getHalf(43); // TypeError
// declared inline
const ref = 1;
const getExact = _$(
a => a === ref,
num => num
);Throws a TypeError for validation failures:
- Missing required parameters
- Type mismatches
- Coercion failures
- Invalid custom type instances
You can optionally specify an expected return type as the third parameter.
- All input type identifiers (
'string','number','boolean','null', etc) - Custom classes (validates instanceof)
- Regular expressions (tests string conversion)
- Array of types for multiple options
- Special types:
'void'orundefined- Must return undefined'any'- Any value except undefined'optional'- Included for completeness, this is the same as not specifying a return type. Return type is not checked.a => a === b- Use any declared or inline function to validate output
// Ensure function returns a string
const upperCase = _$(
'string', str => str.toUpperCase(), 'string'
);
// Validate class instances
// including custom and built in types
const getUser = _$(
'number', id => db.findUser(id), User
);
const getNodes = _$(
[ Node, 'string' ], (el, q) => el.querySelectorAll(q), NodeList
);
// Allow multiple return types
const getValue = _$(
'string', key => cache.get(key), ['string', 'null']
);
// Explicit void return, must return undefined
const logMessage = _$(
'string', msg => { console.log(msg); }, 'void'
);
// Any non-undefined return, null allowed
const process = _$(
'object', data => processData(data), 'any'
);
// Regular Expression test string output
const checkValue = _$(
'string', str => procesValue(str), /^testing$/i
);
// custom validator function
const offset = 10;
const getPositive = _$(
'number', num => num - offset, n => n > 0
);
getPositive(5); // returns -5, would fail validation
// check by reference
const complexTask = _$(
null, doSomething, checkResults
);