drytypes
TypeScript icon, indicating that this package has built-in type declarations

0.6.0 • Public • Published

drytype

DryType is a runtime type-validation library with TypeScript in mind.

Runtime type validations are performed with a runtime type -- a DryType as I've called it throughout this library (beats me why).

A DryType is an object of the type:

export type DryType<T> = {
  validate(param: unknown): ValidationResult;
  // will throw if check fails
  strictValidate(
    param: unknown,
  ): ValidationResult;
  guard(param: unknown): param is T;
  // will throw if check fails
  strictGuard(param: unknown): param is T;
  toString(): string;

  intersect<S>(dt: DryType<S>): DryType<T & S>;
  /*
    errorFrom refers to whether the error from the
    first type, second type, or the default one is
    to be thrown.

    when this is 0 or undefined, the default error is used
    when this is 1, the 'left' error is used
    when this is 2 (or any other value), the 'right' error is used
  */
  union<S>(dt: DryType<S>, errorFrom?: number): DryType<T | S>;

  tag: string;
};

type ValidationResult = {
  success: boolean;
  message?: string;
  in?: string;
};

Might look fancy, but it's actually pretty simple.

validate(param: unknown) is used to check if a value param confirms to the type specification of that DryType, for example

import { String } from "drytype";

String.validate("hello"); // { success: true }
String.validate(20); // { success: false, message: "expected: string, got: number" }

strictValidate is the same as validate, with one big difference: when the validation fails, instead of returning a ValidationResult object, it throws a ValidationError(message)`.

guard and strictGuard are the same as validate and strictValidate, with the difference being that they are TypeScript guards instead of regular boolean returning functions.

union is the same as TypeScript |. A.union(B) returns a new DryType, which now checks if either A or B succeed. For example,

import { Number, String } from "drytype";

String.union(Number).validate(10); // { success: true }

union also takes a second parameter called fromError, which is used when both checks fail. If this is set to 0 or undefined, the default error will be used. If this is set to 1, the custom error from the DryType on the left will be used, if any. Any other value will make it use the custom error from the DryType on the right, if any.

intersect is the same as TypeScript &. A.intersect(B) returns a new DryType, which now checks if both A and B succeed. For example,

import { NumberGreaterThan, NumberLessThan } from "drytype";

// a number between between 5 and 10
NumberGreaterThan(5).intersect(NumberLessThan(10)).validate(7); // { success: true }

That covers what a DryType is composed of. A set of useful DryTypes have been provided by default in the modules directory for convenience. However, creating a new DryType is also very easy.

To create a new DryType, you can use makeDryType, which has the type:

const makeDryType = <T>(
  validator: (x: unknown) => ValidationResult,
  tag = "unknown",
): DryType<T>

Here's an example:

export const Function = makeDryType<Function>(
  (x) => typeof x == "function" ? { success: true } : { success: false },
  "function",
);

The generic type parameter is the type that the validated value should be of. This is used for TypeScript guards. The first parameter is a function that takes x: unknown and validates it. This function has to return a ValidationResult object, where success: boolean is a compulsory field. The message field will never be used if success is true, so you can skip it if success is true. However, if success is false, and you still skip the message field, a default message will be used, which is:

`expected: ${drytypeInQuestion.tag}, got: ${typeof (unknownParam)}${
  result.in == undefined ? "" : `, in: ${result.in}`
}`;

The only use of the in parameter in ValidationResult is to be inserted this way into the default error message. This can be useful for, say, Records where you need to give out additional information about where the validation failed.

NOTE: Also have a look at the tests for an example usage. Every provided DryType has at least one test present.

That's all you need to know to use this library. Happy validatin'!

Readme

Keywords

none

Package Sidebar

Install

npm i drytypes

Weekly Downloads

1

Version

0.6.0

License

GPL-3.0-or-later

Unpacked Size

82.5 kB

Total Files

48

Last publish

Collaborators

  • uditkarode