# Custom Types

Pretty much like with [JSDoc @typedef](https://jsdoc.app/tags-typedef.html) 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.

```javascript
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 `#Hero`that represents an object/namespace required to have properties `hasSuperhumanStrength` and `hasWaterbreathing` both of boolean type.

```javascript
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

```javascript
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

```javascript
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

```javascript
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=" );
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dsheiko.gitbook.io/bycontract/custom-types.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
