0.1.3 • Published 23 days ago

ts-cast v0.1.3

Weekly downloads
-
License
MIT
Repository
github
Last release
23 days ago

ts-cast · Coverage Status npm version npm downloads GitHub license

Runtime type checking for Typescript and JavaScript projects. It allows to specify data structures of the "external" resources (requests to the application or responses from other applications).

The idea is based on the Caster that is a function accepts value of unknown type and returns value of target type or throws a TypeError if casting is impossible.

Additionally ts-cast presents tools for:

  • validation casted data
  • transformation of casted data
  • Either and Validation monads support

Almost in all cases ts-cast allows to avoid specification of correspondent type in TypeScript, because the type could be get as ReturnType of the correspondent caster-function.

const Person = struct({ name: string, age: integer });

type Person = ReturnType<typeof Person>;

// the same as

type Person = { name: string, age: number };

Installation

npm i ts-cast

Documentation

Read ts-cast documentation on github: https://github.com/DScheglov/ts-cast/tree/master/docs

Getting Started

Let's start with an example:

./src/schema.ts

import { integer, number, string, struct, tuple, array, toBe } from 'ts-cast';
import v from 'validator';

export const Person = struct({
  name: string,
  email: string.restrict(toBe(v.isEmail, "a valid email")),
});

export const Coords = tuple(number, number);

export const Book = struct({
  title: string,
  annotation: string.optional,
  year: integer,
  authors: array(Person),
  coords: Coords.optional,
});

export type TPerson = ReturnType<typeof Person>;
export type TCoords = ReturnType<typeof Coords>;
export type TBook = ReturnType<typeof Book>;

Then we can use defined types and their caster-s in this way:

./src/index.ts

import { Person, TPerson, Book, TBook } from './schema';

const me = Person({ name: "John Smith", email: "john@smith.com" });

const meAgain: TPerson = {
  name: "John Smith",
  email: "john.smith@gmail.com", // but email will not be validated with validator.isEmail
};

const myBook = Book({
  title: "My First Book",
  year: 2021,
  authors: [
    me,
    meAgain,
    { name: 'Some Other Guy', email: 'other.guy@gmail.com' },
  ],
  coords: [1.2, 23.32]
}, "myBook");

const book: TBook = myBook;

console.dir(book, { depth: null });

TypeScript Analogy

Primitive Types

ts-castTypeScript
numbernumber
integernumber
stringstring
booleanboolean
nilnull
undefundefined

Example:

import { integer } from 'ts-cast';

const x = integer(10); // works
const y = integer(Math.PI);  // throws TypeError
const z = integet('10'); // also throws TypeError
import { string } from 'ts-cast';

const a = string('Hello Wordl!'); // works
const b = string(''); // also works
const c = string(null); // throws TypeError
const d = string(20); // throws TypeError again

Literal Types

ts-castTypeScriptComments
value(V)V as constV extends number \| string \| boolean \| symbol
values(A, B, C, ...)A \| B \| C ...A, B, C ... extends number \| string \| boolean \| symbol
import { values } from 'ts-cast';

const TrafficLight = values('red', 'yellow', 'green');

const green = TrafficLight('green'); // works

type TypeOfGreen = typeof green; // 'red' | 'yellow' | 'green'

const wrong = TrafficLight('blue'); // throws TypeError

Complex Types

ts-castTypeScript
tuple(caster<T1>, caster<T2>, ...)[T1, T2, ...]
array(caster<T>)T[]
struct({ a: caster<A>, b: caster<B> }){ a: A, b: B }
record(caster<K>, caster<V>)Record<K, V>

Type Modifiers

ts-castTypeScript
caster<T>.optionalT \| undefined
caster<T>.default(v)x: T = v
caster<T>.nullableT \| null
caster<T>.restrict(...)T

Operations over Types

ts-castTypeScript
union(caster<T1>, caster<T2>, ...)T1 \| T2 \| ...
prod(caster<T1>, caster<T2>, ...)T1 & T2 & ...
0.1.3

23 days ago

0.1.2

1 month ago

0.1.0

2 months ago

0.1.1

2 months ago

0.0.11

2 months ago

0.0.10

3 months ago

0.0.9

1 year ago

0.0.8

3 years ago

0.0.7

3 years ago

0.0.6

3 years ago

0.0.5

3 years ago

0.0.4

3 years ago

0.0.3

3 years ago

0.0.2

3 years ago

0.0.1

3 years ago