prover-ts
v1.2.1
Published
Prover-ts is a small lightweight package to parse through unknown shapes, providing strong typing.
Downloads
8
Readme
Prover-ts
Prover-ts is a small lightweight package to parse through unknown shapes, providing strong typing.
Installation
npm install prover-ts
Usage
import { prover } from "prover-ts";
/*
* API returns an object. A familiar shape is known, but strong confirmation is needed.
* Prover-ts can help on that.
*/
try {
const unknownShape = await fetchingSomething(); // unknown
const parsedShape = prover
.object({ name: prover.string(), lastName: prover.string(), age: prover.number() })
.parse(unknownShape);
} catch (error) {
console.log(error);
}
parsedShape
would be typed like this:
const parsedShape: {
name: string;
lastName: string;
age: number;
};
prover-ts would return an error if the object did not match the expected shape. Future releases might change this.
Supported types
String
nonEmpty
expects a non-empty string.
const result = prover.string().nonEmpty().parse("Test"); // Throws prover.string().nonEmpty().parse("");
max
Parameters
maxLength {number}
expected max charactersconst result = prover.string().max(5).parse("Hello"); // Throws prover.string().max(5).parse("Hello World");
min
Parameters
minLength {number}
expected min charactersconst result = prover.string().min(5).parse("Hello"); // Throws prover.string().min(5).parse("Hi");
length
Parameters
length {number}
expected string lengthconst result = prover.string().length(5).parse("Hello"); // Throws prover.string().length(5).parse("Hello again");
includes
Parameters
toInclude {string}
expected string to be presentconst result = prover.string().includes("Hello").parse("Hello World"); // Throws prover.string().includes("Hello").parse("Hi World");
startsWith
Parameters
toStartWith {string}
expected characters matching the beginning of the stringconst result = prover.startsWith("Hello").parse("Hello, world!"); // Throws prover.startsWith("Hello").parse("Hi, world!");
endsWith
Parameters
endsWith {string}
expected characters matching the end of the stringconst result = prover.endsWith("world!").parse("Hello, world!"); // Throws prover.endsWith("world!").parse("Hello, universe!");
regex
Parameters
pattern {string | RegExp}
pattern to matchconst result = prover.regex(/^\d{4}$/).parse("1234"); // Throws prover.regex(/^\d{4}$/).parse("12345");
email
expects an email
const result = prover.email().parse("[email protected]"); // Throws prover.email().parse("invalid-email");
date
expects a date formatted yyyy-mm-dd
const result = prover.date().parse("2023-05-30"); // Throws prover.date().parse("30/05/2023");
future implementation might support different formats
numeric
expects a numeric string
const result = prover.numeric().parse("12345"); // Throws prover.numeric().parse("abc12345");
alphanumeric
expects an alphanumeric string
const result = prover.alphanumeric().parse("abc123"); // Throws prover.alphanumeric().parse("abc@123");
ipv4
expects an ipv4 matching string
const result = prover.ipv4().parse("192.168.0.1"); // Throws prover.ipv4().parse("256.256.256.256");
func
Parameters
predicate {(arg: string) => boolean}
predicate function responsible to validate stringconst isUpperCase = (arg: string) => arg === arg.toUpperCase(); const result = prover.func(isUpperCase).parse("HELLO"); // Throws prover.func(isUpperCase).parse("Hello");
Number
positive
expects a positive number.
const result = prover.number().positive().parse(1); // Throws prover.number().positive().parse(-1);
negative
expects a negative number.
const result = prover.number().negative().parse(-1); // Throws prover.number().negative().parse(1);
equal
toEqual {number}
expects an equal number.const result = prover.number().equal(42).parse(42); // Throws prover.number().equal(42).parse(-1);
gt
Parameters
comp {number}
number to be greater thanconst result = prover.number().gt(42).parse(69); // Throws prover.number().gt(42).parse(22);
gte
Parameters
comp {number}
number to be greater or equal thanconst result = prover.number().gte(42).parse(42); // Throws prover.number().gte(42).parse(24);
lt
Parameters
comp {number}
number to be lesser thanconst result = prover.number().lt(42).parse(24); // Throws prover.number().lt(42).parse(69);
lte
Parameters
comp {number}
number to be lesser or equal toconst result = prover.number().lte(42).parse(42); // Throws prover.number().lte(42).parse(69);
multiple
Parameters
comp {number}
number to be multiple ofconst result = prover.number().multiple(5).parse(10); // Throws prover.number().multiple(3).parse(10);
save
Requires number to be a safe integer, meaning, between Number.MIN_SAFE_INTEGER and Number.MAX_SAFE_INTEGER
const result = prover.number().save().parse(10); // Throws prover.number().save().parse(Infinity);
finite
Requires number to be in between Infinity and -Infinity
const result = prover.number().finite().parse(69); // Throws prover.number().finite().parse(Infinity);
func
Parameters
func {(arg: number) => boolean}
predicate function responsible to validate numberconst isEven = (arg) => arg % 2 === 0; const result = prover.number().func(isEven).parse(10); // Throws prover.number().func(isEven).parse(3);
Object
safe
filters out unexpected properties
const result = prover .object({ name: prover.string().nonEmpty(), age: prover.number().positive() }) .safe() .parse({ name: "John", age: 30, address: ["street 1", "street 2"] });
Without calling safe(), result object would have a
address
property, since prover's default behavior would NOT filter out a property that was not expected to exist.
Other examples
const result = prover .object({ name: prover.string().nonEmpty(), age: prover.number().positive() }) .parse({ name: "John", age: 30 });
const result = prover .object({ name: prover.string().nonEmpty(), idNumber: prover.number().positive(), married: prover.boolean(), address: prover.array(prover.string()), }) .parse({ name: "John", idNumber: 12131313, married: true, address: ["hollywood, beverly hills"] });
Inferred correctly
const result: { name: string; idNumber: number; married: boolean; address: string[] };
Record
When you only care about the values and their types
Examples
const result = prover.record(prover.string()).parse({ name: "John", lastName: "Doe" }); // Throws prover.record(prover.string()).parse({ name: "John", age: 30 });
Array
max
Parameters
{nElements}
number of max elements that should be inside the arrayconst result = prover.array([prover.number()]).max(10).parse([1, 2, 3, 4, 5, 6]); // Throws prover.array([prover.number()]).max(2).parse([1, 2, 3, 4, 5, 6]);
min
Parameters
{nElements}
number of min elements that should be inside the arrayconst result = prover.array([prover.number()]).min(2).parse([1, 2, 3, 4, 5, 6]); // Throws prover.array([prover.number()]).min(10).parse([1, 2, 3, 4, 5, 6]);
size
Parameters
{nElements}
number of exact elements that should be inside the arrayconst result = prover.array([prover.number()]).size(6).parse([1, 2, 3, 4, 5, 6]); // Throws prover.array([prover.number()]).size(10).parse([1, 2, 3, 4, 5, 6]);
nonEmpty
const result = prover.array([prover.number()]).nonEmpty().parse([1, 2, 3, 4, 5, 6]); // Throws prover.array([prover.number()]).nonEmpty().parse([]);
Other Examples
const result = prover.array([prover.number(), prover.string()]).parse([1, 2, "3", 4, "5", 6]); // Throws prover.array([prover.number(), prover.string()]).parse([1, 2, "3", 4, "5", 6, true]);
Inferred correctly
const result: (string | number)[];
Tuple
Examples
prover.tuple([prover.number(), prover.number(), prover.boolean()]).parse([1, 2, true]); // Throws prover.tuple([prover.number(), prover.number(), prover.boolean()]).parse([1, "2", true]);
Record and Tuple are still experimental features.
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
Make sure to include changeset.