flow-typer-js
v0.17.0
Published
Declarative static and runtime type checking
Maintainers
Readme
flow-typer
Declarative static and runtime type checking with Flow.
So you are using Flow to type check your code. That's great but how do you check types for data that is not known before running the code? Like JSON input. Sure, you can use your favorite validation library and do unsafe type casting. Or you write verbose code and do low-level type checking with typeof operator to satisfy Flow's refinement.
flow-typer is giving you collection of functions for writing maintainable type schemas in JavaScript with Flow interoperability.
Features
- support for primitive and composable Flow types
- complete Flow coverage
- type validation functions are pure
- define Flow types with JavaScript
- no transpilation required
- works with ES6+ JavaScript
Installation
npm install --save flow-typer-jsImporting
import typer from "flow-typer-js";Usage
flow-typer exposes a set of functions for type checking at runtime. These functions are constructed in way that allows Flow to infer types and keep refinement of the code. By composing functions, we define a type schema that can be used to create inferred Flow types (static checking) and for validating values with unknown type at runtime.
import {
typeOf,
objectOf,
arrayOf,
tupleOf2,
unionOf2,
literal,
string,
number,
boolean,
maybe
} from "flow-typer-js";// define type schema
const personSchema = objectOf({
name: string,
age: maybe(number),
active: boolean,
gender: unionOf2(literal("male"), literal("female")),
tags: arrayOf(string),
location: tupleOf2(number, number)
});// define Flow type from JS type schema
type PersonT = ReturnType<typeof personSchema>// check value of unknown type against type schema
const person = personSchema(unknownInput);
// => person: PersonT// type schema returns value of specific type
person.name.toUpperCase(); // No error
person.email; // Flow error (unknown attribute)
person.active = 1; // Flow error (boolean value expected)
Errors
Type validation throws TypeValidatorError which contains useful information
about why validation failed and what kind of type is expected.
TypeValidatorError: invalid "string" value type; "array" type expected
...
scope PackageT.dependencies
expected Array<{"name":"string","version":"string"}>
type string
value "flow-typer"
file .../flow-typer-examples/index.js:15:15
- scope - level at which validation failed
- expected - the expected type of input value
- type - the actual type of input value
- value - input value in JSON format
- file - file with position where the validator was called
type TypeValidatorError {
expectedType: string
valueType: string
value: string
typeScope: string
sourceFile: string
}Type Conversions
Primitive types number and string have builtin automatic type conversion. The conversion is extended to array and object values with one element. The coversion is disabled by default and it needs to be enabled for each type validator.
- number type from string value, ex.
"45.61","1e-23" - number type from
nulltoNaN - string type from number value
- boolean string values to boolean type, ex.
"true" "null"string value tonull"undefined"string value toundefined
Object conversions
- primitive type from array values with one element, ex.
["ada"]to"ada" - primitive type from object with one key, ex.
{ name: "ada" }to"ada"
API
These functions will check for specific JavaScript type with correct Flow type refinement.
isNil[deprecated]isNullisUndefisBooleanisNumberisStringisObject
Primitive types
nilnull_tundefundefined_tbooleannumberstringliteral
Complex types
mixedobjectmaybe(schema)objectOf(schemaObject, label)optional(schema)
const schema = objectOf({
username: string,
nickname: optional(string)
});
// => type T = { username: string, nickname: (string | void) }arrayOf(schema, label)
const schema = arrayOf(number); // => type T = number[]tupleOf(...schema[]) [deprecated]tupleOf2(...schema[]) ... tupleOf6
const schema = tupleOf2(string, number); // => type T = [string, number]unionOf(...schema[]) [deprecated]unionOf2(...schema[]) ... unionOf6
const schema = unionOf2(string, number); // => type T = string | numbermapOf(keySchema, valueSchema)
const schema = mapOf(string, boolean); // => type T = { [_string]: boolean }literalOf(...) [deprecated]literal(...)
const schema = literal("male");Utilities
isType(schema): booleangetType(schema): string
const schema = objectOf({
dependencies: arrayOf(objectOf(
name: string,
version: number,
exact: boolean
))
});
getType(schema);
// => { dependencies: Array<{ name: string, version: number, exact: boolean }> }typeOf(schema): Ttype(validator): schema
const date = type((value) => {
if (value instanceof Date) return value;
throw new Error();
});