
Research
2025 Report: Destructive Malware in Open Source Packages
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.
tcomb-validation
Advanced tools
A general purpose JavaScript validation library based on type combinators
If you don't know how to define types with tcomb you may want to take a look at its README file.
The main function is validate:
validate(value, type, [options]) -> ValidationResult
value the value to validatetype a type defined with the tcomb libraryoptions (optional) is an object with the following keys
path: Array<string | number> path prefix for validationcontext: any passed to getValidationErrorMessage (useful for i18n)strict: boolean (default false) if true no additional properties are allowed while validating structsreturns a ValidationResult object containing the result of the validation
Note.
options can be an array (as path prefix) for backward compatibility (deprecated)Example
var t = require('tcomb-validation');
var validate = t.validate;
validate(1, t.String).isValid(); // => false
validate('a', t.String).isValid(); // => true
You can inspect the result to quickly identify what's wrong:
var result = validate(1, t.String);
result.isValid(); // => false
result.firstError().message; // => 'Invalid value 1 supplied to String'
// see `result.errors` to inspect all errors
// null and undefined
validate('a', t.Nil).isValid(); // => false
validate(null, t.Nil).isValid(); // => true
validate(undefined, t.Nil).isValid(); // => true
// strings
validate(1, t.String).isValid(); // => false
validate('a', t.String).isValid(); // => true
// numbers
validate('a', t.Number).isValid(); // => false
validate(1, t.Number).isValid(); // => true
// booleans
validate(1, t.Boolean).isValid(); // => false
validate(true, t.Boolean).isValid(); // => true
// optional values
validate(null, maybe(t.String)).isValid(); // => true
validate('a', maybe(t.String)).isValid(); // => true
validate(1, maybe(t.String)).isValid(); // => false
// functions
validate(1, t.Function).isValid(); // => false
validate(function () {}, t.Function).isValid(); // => true
// dates
validate(1, t.Date).isValid(); // => false
validate(new Date(), t.Date).isValid(); // => true
// regexps
validate(1, t.RegExp).isValid(); // => false
validate(/^a/, t.RegExp).isValid(); // => true
You can express more fine-grained contraints with the refinement syntax:
// a predicate is a function with signature: (x) -> boolean
var predicate = function (x) { return x >= 0; };
// a positive number
var Positive = t.refinement(t.Number, predicate);
validate(-1, Positive).isValid(); // => false
validate(1, Positive).isValid(); // => true
// an object with two numerical properties
var Point = t.struct({
x: t.Number,
y: t.Number
});
validate(null, Point).isValid(); // => false
validate({x: 0}, Point).isValid(); // => false, y is missing
validate({x: 0, y: 'a'}, Point).isValid(); // => false, y is not a number
validate({x: 0, y: 0}, Point).isValid(); // => true
validate({x: 0, y: 0, z: 0}, Point, { strict: true }).isValid(); // => false, no additional properties are allowed
Differences from structs
var Serializable = t.interface({
serialize: t.Function
});
validate(new Point(...), Serializable).isValid(); // => false
Point.prototype.serialize = function () { ... }
validate(new Point(...), Serializable).isValid(); // => true
Lists
// a list of strings
var Words = t.list(t.String);
validate(null, Words).isValid(); // => false
validate(['hello', 1], Words).isValid(); // => false, [1] is not a string
validate(['hello', 'world'], Words).isValid(); // => true
Tuples
// a tuple (width x height)
var Size = t.tuple([Positive, Positive]);
validate([1], Size).isValid(); // => false, height missing
validate([1, -1], Size).isValid(); // => false, bad height
validate([1, 2], Size).isValid(); // => true
var CssTextAlign = t.enums.of('left right center justify');
validate('bottom', CssTextAlign).isValid(); // => false
validate('left', CssTextAlign).isValid(); // => true
var CssLineHeight = t.union([t.Number, t.String]);
validate(null, CssLineHeight).isValid(); // => false
validate(1.4, CssLineHeight).isValid(); // => true
validate('1.2em', CssLineHeight).isValid(); // => true
// a dictionary of numbers
var Country = t.enums.of(['IT', 'US'], 'Country');
var Warranty = t.dict(Country, t.Number, 'Warranty');
validate(null, Warranty).isValid(); // => false
validate({a: 2}, Warranty).isValid(); // => false, ['a'] is not a Country
validate({US: 2, IT: 'a'}, Warranty).isValid(); // => false, ['IT'] is not a number
validate({US: 2, IT: 1}, Warranty).isValid(); // => true
var Min = t.refinement(t.String, function (s) { return s.length > 2; }, 'Min');
var Max = t.refinement(t.String, function (s) { return s.length < 5; }, 'Max');
var MinMax = t.intersection([Min, Max], 'MinMax');
MinMax.is('abc'); // => true
MinMax.is('a'); // => false
MinMax.is('abcde'); // => false
You can validate structures with an arbitrary level of nesting:
var Post = t.struct({
title: t.String,
content: t.String,
tags: Words
});
var mypost = {
title: 'Awesome!',
content: 'You can validate structures with arbitrary level of nesting',
tags: ['validation', 1] // <-- ouch!
};
validate(mypost, Post).isValid(); // => false
validate(mypost, Post).firstError().message; // => 'tags[1] is `1`, should be a `Str`'
You can customise the validation error message defining a function getValidationErrorMessage(value, path, context) on the type constructor:
var ShortString = t.refinement(t.String, function (s) {
return s.length < 3;
});
ShortString.getValidationErrorMessage = function (value) {
if (!value) {
return 'Required';
}
if (value.length >= 3) {
return 'Too long my friend';
}
};
validate('abc', ShortString).firstError().message; // => 'Too long my friend'
In order to keep the validation logic in one place, one may define a custom combinator:
function mysubtype(type, getValidationErrorMessage, name) {
var Subtype = t.refinement(type, function (x) {
return !t.String.is(getValidationErrorMessage(x));
}, name);
Subtype.getValidationErrorMessage = getValidationErrorMessage;
return Subtype;
}
var ShortString = mysubtype(t.String, function (s) {
if (!s) {
return 'Required';
}
if (s.length >= 3) {
return 'Too long my friend';
}
});
Let's design the process for a simple sign in form:
var SignInInfo = t.struct({
username: t.String,
password: t.String
});
// retrieves values from the UI
var formValues = {
username: $('#username').val().trim() || null,
password: $('#password').val().trim() || null
};
// if formValues = {username: null, password: 'password'}
var result = validate(formValues, SignInInfo);
result.isValid(); // => false
result.firstError().message; // => 'Invalid value null supplied to /username: String'
If you don't want to use a JSON Schema validator or it's not applicable, you can just use this lightweight library in a snap. This is the JSON Schema example of http://jsonschemalint.com/
{
"type": "object",
"properties": {
"foo": {
"type": "number"
},
"bar": {
"type": "string",
"enum": [
"a",
"b",
"c"
]
}
}
}
and the equivalent tcomb-validation counterpart:
var Schema = t.struct({
foo: t.Number,
bar: t.enums.of('a b c')
});
let's validate the example JSON:
var json = {
"foo": "this is a string, not a number",
"bar": "this is a string that isn't allowed"
};
validate(json, Schema).isValid(); // => false
// the returned errors are:
- Invalid value "this is a string, not a number" supplied to /foo: Number
- Invalid value "this is a string that isn't allowed" supplied to /bar: "a" | "b" | "c"
Note: A feature missing in standard JSON Schema is the powerful refinement syntax.
ValidationResult represents the result of a validation. It containes the following fields:
errors: a list of ValidationError if validation failsvalue: an instance of type if validation succeded// the definition of `ValidationError`
var ValidationError = t.struct({
message: t.String, // a default message for developers
actual: t.Any, // the actual value being validated
expected: t.Function, // the type expected
path: list(t.union([t.String, t.Number])) // the path of the value
}, 'ValidationError');
// the definition of `ValidationResult`
var ValidationResult = t.struct({
errors: list(ValidationError),
value: t.Any
}, 'ValidationResult');
Returns true if there are no errors.
validate('a', t.String).isValid(); // => true
Returns an object that contains an error message or null if validation succeeded.
validate(1, t.String).firstError().message; // => 'value is `1`, should be a `Str`'
value the value to validatetype a type defined with the tcomb libraryoptions (optional) is an object with the following keys
path: Array<string | number> path prefix for validationcontext: any passed to getValidationErrorMessage (useful for i18n)strict: boolean (default false) if true no additional properties are allowed while validating structsRun npm test
The MIT License (MIT)
Joi is a powerful schema description language and data validator for JavaScript. It allows you to create blueprints or schemas for JavaScript objects to ensure validation. Compared to tcomb-validation, Joi offers a more extensive set of validation rules and is widely used in the Node.js community.
Yup is a JavaScript schema builder for value parsing and validation. It is similar to Joi but is often preferred for its simplicity and ease of use, especially in React applications. Yup provides a more modern API and better integration with form libraries like Formik.
AJV (Another JSON Schema Validator) is a JSON schema validator that is very fast and supports JSON Schema draft-07. It is more focused on JSON schema validation compared to tcomb-validation, which is more about type validation in JavaScript.
FAQs
General purpose validation library for JavaScript
The npm package tcomb-validation receives a total of 800,305 weekly downloads. As such, tcomb-validation popularity was classified as popular.
We found that tcomb-validation demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.

Security News
Socket CTO Ahmad Nassri shares practical AI coding techniques, tools, and team workflows, plus what still feels noisy and why shipping remains human-led.

Research
/Security News
A five-month operation turned 27 npm packages into durable hosting for browser-run lures that mimic document-sharing portals and Microsoft sign-in, targeting 25 organizations across manufacturing, industrial automation, plastics, and healthcare for credential theft.