# @twilio/declarative-type-validator

> Declarative runtime type validator for JavaScript

Latest version **1.0.0** (published 2026-03-18) · MIT license · 0 weekly downloads

## Install

```sh
npm install @twilio/declarative-type-validator
pnpm add @twilio/declarative-type-validator
yarn add @twilio/declarative-type-validator
bun add @twilio/declarative-type-validator
```

## Health

**Score 50/100 (C)** — status: active.

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support.

## Facts

| | |
|---|---|
| Version | 1.0.0 |
| Published | 2026-03-18 |
| First published | 2021-07-13 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Node | >=20 |
| Dependencies | 2 |
| Unpacked size | 435.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | David Lysenko |
| Maintainers | twilio-messaging |

## Links

- npm: https://www.npmjs.com/package/@twilio/declarative-type-validator
- npm.io page: https://npm.io/package/@twilio/declarative-type-validator

## Dependencies (2)

- [core-js](https://npm.io/package/core-js.md) ^3.17.3
- [@babel/runtime](https://npm.io/package/@babel/runtime.md) ^7.17.0

## Recent versions

- 1.0.0 (latest) — 2026-03-18
- 1.0.0-rc.11 (alpha) — 2026-02-27
- 0.1.12-canary.37 (canary) — 2022-04-27
- 0.3.0 — 2026-02-19
- 0.3.0-rc.2 — 2026-02-19
- 0.3.0-rc.0 — 2026-02-19
- 0.2.14-rc.1 — 2026-02-19
- 0.2.14-rc.0 — 2026-02-17
- 0.2.13 — 2025-11-18
- 0.2.13-rc.0 — 2025-11-18
- 0.2.12 — 2025-09-29
- 0.2.12-rc.3 — 2025-09-16
- 0.2.12-rc.0 — 2025-08-01
- 0.2.11 — 2025-07-29
- 0.2.11-rc.19 — 2025-07-11
- … 79 more at https://npm.io/package/@twilio/declarative-type-validator/versions

## README

# Declarative Type Validator

Provides runtime type validation functionality for class methods and functions.

## Usage

Most of the time, using a decorator is the most convenient way to apply type
checking to a class method:

```js
import { validateTypesAsync } from "@twilio/declarative-type-validator";

class TestClass {
  @validateTypes("number")
  someMethod(value) {
    console.log(`value is a number: ${value}`);
  }
}
```

Or if it is an async method, you could use an async version of the decorator, in
which case the type error will be thrown as a rejected promise:

```js
import { validateTypesAsync } from "@twilio/declarative-type-validator";

class TestClass {
  @validateTypesAsync("number")
  async someMethod(value) {
    console.log(`value is a number: ${value}`);
  }
}
```

Each argument passed into the decorator should be a valid rule that corresponds
to the respective argument of the method being decorated. If an argument
requires more than one check, you can pass an array of rules which will get
applied following the OR logic:

```js
import { validateTypesAsync } from "@twilio/declarative-type-validator";

class TestClass {
  @validateTypes(["number", "string"])
  someMethod(value) {
    console.log(`value is either a number or a string: ${value}`);
  }

  @validateTypes("string", ["number", "boolean"])
  someOtherMethod(value, secondValue) {
    console.log(`value is a string: ${value}`);
    console.log(`secondValue is either a number or a boolean: ${secondValue}`);
  }
}
```

Since constructors can't be decorated the same way that normal methods can,
you could utilize the `validateConstructorTypes` decorator (applied to the 
class itself, as opposed to the constructor method) to apply argument validation
to the constructor:

```js
import { validateConstructorTypes } from "@twilio/declarative-type-validator";

@validateConstructorTypes("string", ["number", "boolean"])
class TestClass {
  constructor(value, secondValue) {
    console.log(`value is a string: ${value}`);
    console.log(`secondValue is either a number or a boolean: ${secondValue}`);
  }
}
```

For functions outside of classes, you can utilize `runtimeTypeValidation` 
function instead. It accepts two arguments, first being the array of rules (each
element of the array corresponding to an *array* of rules for the respective 
argument), with the second being the arguments to validate.

Here's an example of the two methods from previous example rewritten using the
`runtimeTypeValidation` function:

```js
import { runtimeTypeValidation } from "@twilio/declarative-type-validator";

function someFunction(value) {
  runtimeTypeValidation([[type("number")]], [value]);

  console.log(`value is a number: ${value}`);
}

function someOtherFunction(value, secondValue) {
  runtimeTypeValidation(
    [[type("string")], [type("number", "boolean")]],
    [value, secondValue]
  );

  console.log(`value is a string: ${value}`);
  console.log(`secondValue is either a number or a boolean: ${secondValue}`);
}
```

## Rules

Type validator comes with a few prebuilt rules. They come in two shapes: rule
factories and rule constants.

Rule factories are functions which generate an object describing the validation
rule. Every single rule factory accepts one or multiple arguments. The rule 
factories are:

 * `type`
 * `literal`
 * `custom`
 * `objectSchema`
 * `array`

Rule constants are pre-made rule objects which don't require any parameters.
The rule constants are:

 * `nonEmptyString`
 * `nonNegativeInteger`
 * `pureObject`

### `type`

Validates against *either* a primitive type (`typeof x`) *or* a constructor 
function (`instanceof x`). If multiple arguments are passed, then they will be 
applied following the OR logic. 

#### Note

Using the `type` rule factory itself could be omitted if a string representing a
primitive type or a constructor function is passed *as a rule itself*.

#### Examples

##### Single primitive type

```js
@validateTypes(type("number"))
// OR
@validateTypes("number")
```

##### Multiple primitive types for the same argument

```js
@validateTypes(["number", "string"])
// OR
@validateTypes(type("number", "string"))
// OR
@validateTypes([type("number"), type("string")])
```

##### Single constructor function (class)

```js
@validateTypes(FormData)
```

##### Multiple constructor functions (classes) for the same argument

```js
@validateTypes([FormData, Blob])
// OR
@validateTypes(type(FormData, Blob))
// OR
@validateTypes([type(FormData), type(Blob)])
```

### `literal`

Validates against a literal value (compared using the strict equality operator 
`===`). If multiple arguments are passed, then they will be applied following 
the OR logic. 

#### Examples

##### Single literal

```js
@validateTypes(literal("foobar"))
```

##### Multiple literals for the same argument

```js
@validateTypes(literal("foobar", 15))
// OR
@validateTypes([literal("foobar"), literal(15)])
```

### `custom`

Validates against a custom rule. The custom rule is represented as a function
that returns a tuple of type `[boolean, string]` where the boolean is whether
the check has passed and the string is the description of the rule. The value 
to validate gets passed as the first argument. 

If multiple arguments are passed to the custom rule, then they will be applied
following the OR logic. 

#### Examples

##### Validate that a number is greater than 15

```js
@validateTypes(
  custom((value) => [
    typeof value === "number" && value > 15,
    "a number greater than 15",
  ])
)
```

### `nonEmptyString`

Validates a non-empty string.

#### Example

```js
@validateTypes(nonEmptyString)
```

### `nonNegativeInteger`

Validates a non-negative integer. I.E., it should contain no decimal point and 
be greater than or equal to 0.

#### Example

```js
@validateTypes(nonNegativeInteger)
```

### `pureObject`

Validates an object that is not `null` and is not an array.

#### Example

```js
@validateTypes(pureObject)
```

### `objectSchema`

Validates an object against a schema. The first argument is a short description
of the object (which will appear in runtime type errors) with the second
argument being the schema itself. The rule will validates every key of the
schema object against a rule (or a set of rules) defined as values.

#### Examples

##### A simple object schema

```js
@validateTypes(
  objectSchema("network configuration", {
    port: "number",
    protocol: literal("http", "https"),
    retries: custom((value) => [
      typeof value === "number" && value > 0 && value < 16,
      "a value between 0 (exclusive) and 15 (inclusive)"
    ])
  })
)
```

##### A nested object schema

```js
@validateTypes(
  objectSchema("root object", {
    foo: ["boolean", "number"],
    bar: objectSchema("child object", {
      baz: "number",
    }),
  })
)
```

### `array`

Validates an array. The first argument is the description of the expected items
in the plural form (E.G.: "items" or "numbers"). The second argument is the rule
(or an array of rules, if there are multiple) that each element of the array
should conform to.

#### Examples

##### An array of numbers

```js
@validateTypes(array("numbers", "number"))
```

##### An array of numbers and/or strings

```js
@validateTypes(array("numbers and/or strings", ["number", "string"]))
```

##### An array of arrays of numbers

```js
@validateTypes(array("arrays of numbers", array("numbers", "number")))
```

---
_Source: https://npm.io/package/@twilio/declarative-type-validator · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
