Define and validate types in js
npm install type-definitionsThe purpose of this package is to allow for defining type/object structure in an
easily recognizable JSON format. An example definition might look something like:
``javascript
import { defineType } from 'type-definitions';
const myTypeDefinition = defineType({
foo: String,
bar: Number,
baz: {
test: Boolean,
something: [String]
}
})
`
It also offers validation of values based on those definitions:
`javascript
import { defineType } from 'type-definitions';
const aNumber = defineType(Number);
aNumber.isOfType(2); // true
aNumber.isOfType("test"); // false
const arrayOfStringsOrNumbers = defineType([String, Number]);
arrayOfStringsOrNumbers.isOfType([1, "test"]); // true
arrayOfStringsOrNumbers.isOfType([1, "test", true]); // false
const complexObject = defineType({
a: Number,
b: String,
c: {
d: [String],
e: Boolean
}
});
complex.isOfType({
a: 2,
b: "test",
c: {
d: ["some", "value"],
e: true
}
}); // true
complex.isOfType({
a: 2,
b: "test",
c: {
d: ["some", "value"],
e: "true"
}
}); // false (a.e !== Boolean)
`
Finally, it offers a way to construct objects of a given type and set defaults for that construction:
`javascript
import { defineType, defaultValue, types } from 'type-definition';
const defaultString = defineType(String);
const fooString = defineType(defaultValue(String, "foo"));
const barString = types.String.withDefault("bar");
defaultString.create(); // ''
fooString.create() // 'foo'
barString.create() // 'bar'
barString.create("some other string") // 'some other string'
barString.create(2) // throws error, invalid type
const customObject = types.Object.withDefinition({
a: String,
b: types.Number.withDefault(5),
c: {
d: Boolean,
e: defaultValue(Boolean, true)
}
})
customObject.create() // { a: '', b: 5, c: { d: false, e: true } }
customObject.create({ a: 'test', c: { d: true }}); // { a: 'test', b: 5, c: { d: true, e: true } }
`
This function will process the input and return the representation as a class
with an isOfType static function. It is primarily for coercing native
representations, and will pass through the package-defined types.
Therefore it's always good to wrap your definitions in this so that they
will support as much definition styles as possible.
Validates true for string values (ie "test").
Default value: ""
Using package type:
`javascript
import { types, defineType } from 'type-definitions';
const aString = defineType(types.String);
`
This also supports coercion from native String:
`javascript`
const aString = defineType(String);
Validates true for number values (ie 1, 1.23, Infinity, NaN, 1.0003e+23).
Default value: 0
Using package type:
`javascript
import { types, defineType } from 'type-definitions';
const aNumber = defineType(types.Number);
`
This also supports coercion from native Number:
`javascript`
const aNumber = defineType(Number);
Validates true for boolean values (ie true, false)
Default value: false
Using package type:
`javascript
import { types, defineType } from 'type-definitions';
const aBool = defineType(types.Boolean);
`
This also supports coercion from native Boolean:
`javascript`
const aBool = defineType(Boolean);
Validates true for any array (ie [], ["test"], ["test", 2, true])
Default value: []
Using package type:
`javascript
import { types, defineType } from 'type-definitions';
const anArray = defineType(types.Array);
`
This also supports coercion from native Array or empty Array literal ([]):
`javascript`
const anArray = defineType(Array);
const anotherArray = defineType([]);
Validates true for any array that matches type, including empty arrays (ie for types.Array.ofType(type.String), [] or ["test"])
You can also make an of Array of multiple types which will set the type to a
Union of the types supplied
Default value: []
Using package type:
`javascript
import { types, defineType } from 'type-definitions';
const anArrayOfStrings = defineType(types.Array.ofType(types.String));
`
This also supports coercion from an Array literal with types as members ([String], [String, Number]):
`javascript`
const anArrayOfStrings = defineType([String]);
const anArrayOfStringsOrNumbers = defineType([String, Number]);
Validates true for an object ({}, new class Test {}). Does not match null or arrays.
Default value: {}
Using package type:
`javascript
import { types, defineType } from 'type-definitions';
const anObject = defineType(types.Object);
`
This also supports coercion from native Object and an empty object literal ({})""
`javascript`
const anObject = defineType(Object);
const anotherObject = defineType({});
Validates true for objects that match the defined structure. Note: it will
match objects with additional properties not included in the definition by
default. You can include the strict
Default value: default values of individual props
Using package type:
`javascript
import { types, defineType } from 'type-definitions';
const anObject = defineType(types.Object.withDefinition({
foo: String,
bar: Number
}));
`
This also supports coercion from an Object literal with members ({foo: String, bar: Number }):
`javascript`
const anObject = defineType({
foo: String,
bar: Number
});
Same as Object.withDefinition(objectDefinition) except it also validates that
value does not have any additional keys
Default value: default values of individual props
Using package type:
`javascript
import { types, defineType } from 'type-definitions';
const anObject = defineType(types.Object.withDefinition({
foo: String,
bar: Number
}).strict);
`
There is no native representation of this, however you can import the strict
function and use that to wrap native types:
`javascript
import { defineType, strict } from 'type-definitions';
const aStringOrNull = defineType(strict({
foo: String,
bar: Number
}));
`
Validates true for an object where all values match the supplied value type.
Default value: {}
Using package type:
`javascript
import { types, defineType } from 'type-definitions';
const aHashOfStrings = defineType(types.Object.keyValuePair(String));
`
There is no native representation for this
Validates true for any value (allows null but excludes undefined).
Default value: null
Using package type:
`javascript
import { types, defineType } from 'type-definitions';
const anyType = defineType(types.Any);
`
There is no native representation for this
Validates true for any value matches any of the union types.
Default value: default value of first type
Using package type:
`javascript
import { types, defineType } from 'type-definitions';
const unionOfStringAndNumber = defineType(types.Union.ofType(String, Number));
`
There is no native representation of this, however you can import the unionOf
function and use that to wrap native types:
`javascript
import { defineType, unionOf } from 'type-definitions';
const unionOfStringAndNumber = unionOf(String, Number)
`
All built in types include can be modified to validate for null/undefined by appending
the .optional modifier
Default value: null unless user specified
Using package type:
`javascript
import { types, defineType } from 'type-definitions';
const aStringOrNull = defineType(types.String.optional);
`
There is no native representation of this, however you can import the optional
function and use that to wrap native types:
`javascript
import { defineType, unionOf } from 'type-definitions';
const aStringOrNull = optional(String)
`
Custom classes can be supported by providing a static isOfType(val) method on
your class. It will leverage whatever logic you put in this method for validation
Default value: Object.create(CustomClass)
`javascript
class MyClass {
static isOfType(val) {
return val.__type === "myType"
}
get __type() { return "myType"; }
}
class SomeOtherClass {
get __type() { return "!!!"; }
}
defineType(MyType).isOfType(new SomeOtherClass()); // false
`
_If you use a class that does not define state isOfType(val) then isOfTypeinstanceof
will fall back to using for validation_
Taking an exisitng type and calling .create(val) on it will construct an instance of
of that type with the given value (assuming the provided value validates).
If no value is provided it will construct an object with the _default_ value of
an object (see defaults above)
If you would like to change the default value of an object there is a withDefault() static on allBaseType
type extending from (or coerced via defineType) which takes a default value, validatesdefaultValue(type, val)
it against the type and if it's value uses that as the default construction value. Additionally
there is a method exported for use in wrapping native types
For objects, you can provide a partial value to .create()` and it will use defaults to fill
in other properties as it is able to.