Custom Types

Pretty much like with JSDoc @typedef one can declare a custom type and use it as a contract.

Validating against a Union Type

Here we define a union type for values that can contain either numbers or strings that represent numbers.

import { validate, typedef } from "bycontract";
typedef( "NumberLike", "number|string" );
validate( 10, "NumberLike" ); // OK
validate( null, "NumberLike" ); // ByContractError: expected number|string but got null

Validating against a Complex Type

This example defines a type #Herothat represents an object/namespace required to have properties hasSuperhumanStrength and hasWaterbreathing both of boolean type.

import { validate, typedef } from "bycontract";
typedef( "#Hero", {
hasSuperhumanStrength: "boolean",
hasWaterbreathing: "boolean"
});
var superman = {
hasSuperhumanStrength: true,
hasWaterbreathing: false
};
validate( superman, "#Hero" ); // OK

Custom type in the example above is prefixed with sharp (#) to avoid interfering with global objects. It's not required though.

When any of properties violates the specified contract an exception thrown

var superman = {
hasSuperhumanStrength: 42,
hasWaterbreathing: null
};
validate( superman, "#Hero" );
// ByContractError: property #hasSuperhumanStrength expected boolean but got number

If value misses a property of the complex type an exception thrown

var auqaman = {
hasWaterbreathing: true
};
validate( superman, "#Hero" );
// ByContractError: missing required property #hasSuperhumanStrength

Custom Types and modifiers

Custom type is treated the same way as any other type in JSDoc

typedef( "#Hero", {
hasSuperhumanStrength: "boolean",
hasWaterbreathing: "boolean"
});
‚Äč
validate( { foo: superman }, "Object.<string, #Hero>" );
validate( "text", "string|#Hero" );
validate( [ superman ], "#Hero[]" );
validate( null, "?#Hero" );
validate( false, "#Hero=" );