Comparing version 0.13.1 to 1.0.0
{ | ||
"typescript.tsdk": "./node_modules/typescript/lib", | ||
"typescript.tsdk": "./node_modules/typescript/lib", | ||
// Files to exclude from the sidebar | ||
"files.exclude": { | ||
"lib/": true, | ||
"coverage/": true | ||
} | ||
} | ||
// Files to exclude from the sidebar | ||
"files.exclude": { | ||
"lib/": true, | ||
"coverage/": true | ||
} | ||
} |
{ | ||
// See https://go.microsoft.com/fwlink/?LinkId=733558 | ||
// for the documentation about the tasks.json format | ||
"version": "2.0.0", | ||
"tasks": [ | ||
{ | ||
"type": "npm", | ||
"script": "build:watch", | ||
"group": { | ||
"kind": "build", | ||
"isDefault": true | ||
} | ||
} | ||
] | ||
} | ||
// See https://go.microsoft.com/fwlink/?LinkId=733558 | ||
// for the documentation about the tasks.json format | ||
"version": "2.0.0", | ||
"tasks": [ | ||
{ | ||
"type": "npm", | ||
"script": "build:watch", | ||
"group": { | ||
"kind": "build", | ||
"isDefault": true | ||
} | ||
} | ||
] | ||
} |
@@ -23,5 +23,5 @@ "use strict"; | ||
return returnType.check(f.apply(void 0, args)); | ||
}; } | ||
}; }, | ||
}; | ||
} | ||
exports.Contract = Contract; |
@@ -22,2 +22,2 @@ export { Runtype, Static } from './runtype'; | ||
export * from './types/constraint'; | ||
export { InstanceOf } from "./types/instanceof"; | ||
export { InstanceOf } from './types/instanceof'; |
@@ -5,3 +5,3 @@ import { Runtype } from './runtype'; | ||
import { ConstraintCheck } from './types/constraint'; | ||
import { Constructor } from "./types/instanceof"; | ||
import { Constructor } from './types/instanceof'; | ||
export declare type Reflect = { | ||
@@ -8,0 +8,0 @@ tag: 'always'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var show = function (needsParens) { return function (refl) { | ||
var parenthesize = function (s) { return needsParens ? "(" + s + ")" : s; }; | ||
var parenthesize = function (s) { return (needsParens ? "(" + s + ")" : s); }; | ||
switch (refl.tag) { | ||
@@ -18,5 +18,3 @@ // Primitive types | ||
var value = refl.value; | ||
return typeof value === 'string' | ||
? "\"" + value + "\"" | ||
: String(value); | ||
return typeof value === 'string' ? "\"" + value + "\"" : String(value); | ||
} | ||
@@ -29,11 +27,11 @@ case 'array': | ||
var keys = Object.keys(refl.fields); | ||
return keys.length ? "{ " + keys | ||
.map(function (k) { return k + ": " + show(false)(refl.fields[k]) + ";"; }) | ||
.join(' ') + " }" : '{}'; | ||
return keys.length | ||
? "{ " + keys.map(function (k) { return k + ": " + show(false)(refl.fields[k]) + ";"; }).join(' ') + " }" | ||
: '{}'; | ||
} | ||
case 'partial': { | ||
var keys = Object.keys(refl.fields); | ||
return keys.length ? "{ " + keys | ||
.map(function (k) { return k + "?: " + show(false)(refl.fields[k]) + ";"; }) | ||
.join(' ') + " }" : '{}'; | ||
return keys.length | ||
? "{ " + keys.map(function (k) { return k + "?: " + show(false)(refl.fields[k]) + ";"; }).join(' ') + " }" | ||
: '{}'; | ||
} | ||
@@ -50,5 +48,5 @@ case 'tuple': | ||
var name = refl.ctor.name; | ||
return "InstanceOf<" + (name) + ">"; | ||
return "InstanceOf<" + name + ">"; | ||
} | ||
}; }; | ||
exports.default = show(false); |
@@ -1,2 +0,2 @@ | ||
import { Runtype } from "../runtype"; | ||
import { Runtype } from '../runtype'; | ||
export interface Constructor<V> { | ||
@@ -6,5 +6,5 @@ new (...args: any[]): V; | ||
export interface InstanceOf<V> extends Runtype<V> { | ||
tag: "instanceof"; | ||
tag: 'instanceof'; | ||
ctor: Constructor<V>; | ||
} | ||
export declare function InstanceOf<V>(ctor: Constructor<V>): InstanceOf<V>; |
@@ -10,4 +10,4 @@ "use strict"; | ||
return x; | ||
}, { tag: "instanceof", ctor: ctor }); | ||
}, { tag: 'instanceof', ctor: ctor }); | ||
} | ||
exports.InstanceOf = InstanceOf; |
@@ -9,3 +9,5 @@ "use strict"; | ||
var data = { | ||
get tag() { return getWrapped()['tag']; } | ||
get tag() { | ||
return getWrapped()['tag']; | ||
}, | ||
}; | ||
@@ -12,0 +14,0 @@ var cached; |
@@ -1,41 +0,51 @@ | ||
import { Runtype, Static } from '../runtype'; | ||
export interface Union1<A extends Runtype> extends Runtype<Static<A>> { | ||
import { Runtype as Rt, Static } from '../runtype'; | ||
export interface Union1<A extends Rt> extends Rt<Static1<A>> { | ||
tag: 'union'; | ||
alternatives: [A]; | ||
match: Match1<A>; | ||
} | ||
export interface Union2<A extends Runtype, B extends Runtype> extends Runtype<Static<A> | Static<B>> { | ||
export interface Union2<A extends Rt, B extends Rt> extends Rt<Static2<A, B>> { | ||
tag: 'union'; | ||
alternatives: [A, B]; | ||
match: Match2<A, B>; | ||
} | ||
export interface Union3<A extends Runtype, B extends Runtype, C extends Runtype> extends Runtype<Static<A> | Static<B> | Static<C>> { | ||
export interface Union3<A extends Rt, B extends Rt, C extends Rt> extends Rt<Static3<A, B, C>> { | ||
tag: 'union'; | ||
alternatives: [A, B, C]; | ||
match: Match3<A, B, C>; | ||
} | ||
export interface Union4<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype> extends Runtype<Static<A> | Static<B> | Static<C> | Static<D>> { | ||
export interface Union4<A extends Rt, B extends Rt, C extends Rt, D extends Rt> extends Rt<Static<A> | Static<B> | Static<C> | Static<D>> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D]; | ||
match: Match4<A, B, C, D>; | ||
} | ||
export interface Union5<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype> extends Runtype<Static<A> | Static<B> | Static<C> | Static<D> | Static<E>> { | ||
export interface Union5<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt> extends Rt<Static<A> | Static<B> | Static<C> | Static<D> | Static<E>> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D, E]; | ||
match: Match5<A, B, C, D, E>; | ||
} | ||
export interface Union6<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype> extends Runtype<Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F>> { | ||
export interface Union6<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt> extends Rt<Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F>> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D, E, F]; | ||
match: Match6<A, B, C, D, E, F>; | ||
} | ||
export interface Union7<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype> extends Runtype<Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G>> { | ||
export interface Union7<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt> extends Rt<Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G>> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D, E, F, G]; | ||
match: Match7<A, B, C, D, E, F, G>; | ||
} | ||
export interface Union8<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype> extends Runtype<Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H>> { | ||
export interface Union8<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt, H extends Rt> extends Rt<Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H>> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D, E, F, G, H]; | ||
match: Match8<A, B, C, D, E, F, G, H>; | ||
} | ||
export interface Union9<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype> extends Runtype<Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H> | Static<I>> { | ||
export interface Union9<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt, H extends Rt, I extends Rt> extends Rt<Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H> | Static<I>> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D, E, F, G, H, I]; | ||
match: Match9<A, B, C, D, E, F, G, H, I>; | ||
} | ||
export interface Union10<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype, J extends Runtype> extends Runtype<Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H> | Static<I> | Static<J>> { | ||
export interface Union10<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt, H extends Rt, I extends Rt, J extends Rt> extends Rt<Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H> | Static<I> | Static<J>> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D, E, F, G, H, I, J]; | ||
match: Match10<A, B, C, D, E, F, G, H, I, J>; | ||
} | ||
@@ -45,11 +55,52 @@ /** | ||
*/ | ||
export declare function Union<A extends Runtype>(A: A): Union1<A>; | ||
export declare function Union<A extends Runtype, B extends Runtype>(A: A, B: B): Union2<A, B>; | ||
export declare function Union<A extends Runtype, B extends Runtype, C extends Runtype>(A: A, B: B, C: C): Union3<A, B, C>; | ||
export declare function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype>(A: A, B: B, C: C, D: D): Union4<A, B, C, D>; | ||
export declare function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype>(A: A, B: B, C: C, D: D, E: E): Union5<A, B, C, D, E>; | ||
export declare function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype>(A: A, B: B, C: C, D: D, E: E, F: F): Union6<A, B, C, D, E, F>; | ||
export declare function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype>(A: A, B: B, C: C, D: D, E: E, F: F, G: G): Union7<A, B, C, D, E, F, G>; | ||
export declare function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype>(A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H): Union8<A, B, C, D, E, F, G, H>; | ||
export declare function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype>(A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, I: I): Union9<A, B, C, D, E, F, G, H, I>; | ||
export declare function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype, J extends Runtype>(A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, I: I, J: J): Union10<A, B, C, D, E, F, G, H, I, J>; | ||
export declare function Union<A extends Rt>(A: A): Union1<A>; | ||
export declare function Union<A extends Rt, B extends Rt>(A: A, B: B): Union2<A, B>; | ||
export declare function Union<A extends Rt, B extends Rt, C extends Rt>(A: A, B: B, C: C): Union3<A, B, C>; | ||
export declare function Union<A extends Rt, B extends Rt, C extends Rt, D extends Rt>(A: A, B: B, C: C, D: D): Union4<A, B, C, D>; | ||
export declare function Union<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt>(A: A, B: B, C: C, D: D, E: E): Union5<A, B, C, D, E>; | ||
export declare function Union<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt>(A: A, B: B, C: C, D: D, E: E, F: F): Union6<A, B, C, D, E, F>; | ||
export declare function Union<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt>(A: A, B: B, C: C, D: D, E: E, F: F, G: G): Union7<A, B, C, D, E, F, G>; | ||
export declare function Union<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt, H extends Rt>(A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H): Union8<A, B, C, D, E, F, G, H>; | ||
export declare function Union<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt, H extends Rt, I extends Rt>(A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, I: I): Union9<A, B, C, D, E, F, G, H, I>; | ||
export declare function Union<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt, H extends Rt, I extends Rt, J extends Rt>(A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, I: I, J: J): Union10<A, B, C, D, E, F, G, H, I, J>; | ||
export interface Match1<A extends Rt> { | ||
<Z>(cases: [Case<A, Z>]): (x: Static1<A>) => Z; | ||
} | ||
export interface Match2<A extends Rt, B extends Rt> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>]): (x: Static2<A, B>) => Z; | ||
} | ||
export interface Match3<A extends Rt, B extends Rt, C extends Rt> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>, Case<C, Z>]): (x: Static3<A, B, C>) => Z; | ||
} | ||
export interface Match4<A extends Rt, B extends Rt, C extends Rt, D extends Rt> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>, Case<C, Z>, Case<D, Z>]): (x: Static4<A, B, C, D>) => Z; | ||
} | ||
export interface Match5<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>, Case<C, Z>, Case<D, Z>, Case<E, Z>]): (x: Static5<A, B, C, D, E>) => Z; | ||
} | ||
export interface Match6<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>, Case<C, Z>, Case<D, Z>, Case<E, Z>, Case<F, Z>]): (x: Static6<A, B, C, D, E, F>) => Z; | ||
} | ||
export interface Match7<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>, Case<C, Z>, Case<D, Z>, Case<E, Z>, Case<F, Z>, Case<G, Z>]): (x: Static7<A, B, C, D, E, F, G>) => Z; | ||
} | ||
export interface Match8<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt, H extends Rt> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>, Case<C, Z>, Case<D, Z>, Case<E, Z>, Case<F, Z>, Case<G, Z>, Case<H, Z>]): (x: Static8<A, B, C, D, E, F, G, H>) => Z; | ||
} | ||
export interface Match9<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt, H extends Rt, I extends Rt> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>, Case<C, Z>, Case<D, Z>, Case<E, Z>, Case<F, Z>, Case<G, Z>, Case<H, Z>, Case<I, Z>]): (x: Static9<A, B, C, D, E, F, G, H, I>) => Z; | ||
} | ||
export interface Match10<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt, H extends Rt, I extends Rt, J extends Rt> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>, Case<C, Z>, Case<D, Z>, Case<E, Z>, Case<F, Z>, Case<G, Z>, Case<H, Z>, Case<I, Z>, Case<J, Z>]): (x: Static10<A, B, C, D, E, F, G, H, I, J>) => Z; | ||
} | ||
export declare type Case<T extends Rt, Result> = (v: Static<T>) => Result; | ||
export declare type Static1<A extends Rt> = Static<A>; | ||
export declare type Static2<A extends Rt, B extends Rt> = Static<A> | Static<B>; | ||
export declare type Static3<A extends Rt, B extends Rt, C extends Rt> = Static<A> | Static<B> | Static<C>; | ||
export declare type Static4<A extends Rt, B extends Rt, C extends Rt, D extends Rt> = Static<A> | Static<B> | Static<C> | Static<D>; | ||
export declare type Static5<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt> = Static<A> | Static<B> | Static<C> | Static<D> | Static<E>; | ||
export declare type Static6<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt> = Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F>; | ||
export declare type Static7<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt> = Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G>; | ||
export declare type Static8<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt, H extends Rt> = Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H>; | ||
export declare type Static9<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt, H extends Rt, I extends Rt> = Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H> | Static<I>; | ||
export declare type Static10<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt, F extends Rt, G extends Rt, H extends Rt, I extends Rt, J extends Rt> = Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H> | Static<I> | Static<J>; |
@@ -9,2 +9,9 @@ "use strict"; | ||
} | ||
var match = function (cases) { return function (x) { | ||
for (var i = 0; i < alternatives.length; i++) { | ||
if (alternatives[i].guard(x)) { | ||
return cases[i](x); | ||
} | ||
} | ||
}; }; | ||
return runtype_1.create(function (x) { | ||
@@ -17,4 +24,4 @@ for (var _i = 0, alternatives_1 = alternatives; _i < alternatives_1.length; _i++) { | ||
throw new Error('No alternatives were matched'); | ||
}, { tag: 'union', alternatives: alternatives }); | ||
}, { tag: 'union', alternatives: alternatives, match: match }); | ||
} | ||
exports.Union = Union; |
{ | ||
"name": "runtypes", | ||
"version": "0.13.1", | ||
"version": "1.0.0", | ||
"description": "Runtime validation for static types", | ||
@@ -10,2 +10,3 @@ "main": "./lib/index.js", | ||
"build:watch": "tsc --noEmit --pretty --watch", | ||
"format": "prettier $([ \"$CI\" == true ] && echo --list-different || echo --write) './**/*.{ts,tsx,js,json,css}'", | ||
"test": "yarn build && jest --no-cache --verbose --coverage", | ||
@@ -21,2 +22,3 @@ "test:watch": "jest --watchAll", | ||
"jest": "21.2.1", | ||
"prettier": "^1.10.2", | ||
"ts-jest": "^21.1.4", | ||
@@ -23,0 +25,0 @@ "typescript": "2.6.1" |
@@ -1,44 +0,30 @@ | ||
import { Runtype } from './index' | ||
import { validationError } from './runtype' | ||
import { Runtype } from './index'; | ||
import { validationError } from './runtype'; | ||
export interface Contract0<Z> { | ||
enforce( | ||
f: () => Z | ||
): () => Z | ||
enforce(f: () => Z): () => Z; | ||
} | ||
export interface Contract1<A, Z> { | ||
enforce( | ||
f: (a: A) => Z | ||
): (a: A) => Z | ||
enforce(f: (a: A) => Z): (a: A) => Z; | ||
} | ||
export interface Contract2<A, B, Z> { | ||
enforce( | ||
f: (a: A, b: B) => Z | ||
): (a: A, b: B) => Z | ||
enforce(f: (a: A, b: B) => Z): (a: A, b: B) => Z; | ||
} | ||
export interface Contract3<A, B, C, Z> { | ||
enforce( | ||
f: (a: A, b: B, c: C) => Z | ||
): (a: A, b: B, c: C) => Z | ||
enforce(f: (a: A, b: B, c: C) => Z): (a: A, b: B, c: C) => Z; | ||
} | ||
export interface Contract4<A, B, C, D, Z> { | ||
enforce( | ||
f: (a: A, b: B, c: C, d: D) => Z | ||
): (a: A, b: B, c: C, d: D) => Z | ||
enforce(f: (a: A, b: B, c: C, d: D) => Z): (a: A, b: B, c: C, d: D) => Z; | ||
} | ||
export interface Contract5<A, B, C, D, E, Z> { | ||
enforce( | ||
f: (a: A, b: B, c: C, d: D, e: E) => Z | ||
): (a: A, b: B, c: C, d: D, e: E) => Z | ||
enforce(f: (a: A, b: B, c: C, d: D, e: E) => Z): (a: A, b: B, c: C, d: D, e: E) => Z; | ||
} | ||
export interface Contract6<A, B, C, D, E, F, Z> { | ||
enforce( | ||
f: (a: A, b: B, c: C, d: D, e: E, f: F) => Z | ||
): (a: A, b: B, c: C, d: D, e: E, f: F) => Z | ||
enforce(f: (a: A, b: B, c: C, d: D, e: E, f: F) => Z): (a: A, b: B, c: C, d: D, e: E, f: F) => Z; | ||
} | ||
@@ -48,4 +34,4 @@ | ||
enforce( | ||
f: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => Z | ||
): (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => Z | ||
f: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => Z, | ||
): (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => Z; | ||
} | ||
@@ -55,4 +41,4 @@ | ||
enforce( | ||
f: (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) => Z | ||
): (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) => Z | ||
f: (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) => Z, | ||
): (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H) => Z; | ||
} | ||
@@ -62,4 +48,4 @@ | ||
enforce( | ||
f: (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I) => Z | ||
): (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I) => Z | ||
f: (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I) => Z, | ||
): (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I) => Z; | ||
} | ||
@@ -69,4 +55,4 @@ | ||
enforce( | ||
f: (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J) => Z | ||
): (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J) => Z | ||
f: (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J) => Z, | ||
): (a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J) => Z; | ||
} | ||
@@ -77,14 +63,5 @@ | ||
*/ | ||
export function Contract<Z>( | ||
Z: Runtype<Z>, | ||
): Contract0<Z> | ||
export function Contract<A, Z>( | ||
A: Runtype<A>, | ||
Z: Runtype<Z>, | ||
): Contract1<A, Z> | ||
export function Contract<A, B, Z>( | ||
A: Runtype<A>, | ||
B: Runtype<B>, | ||
Z: Runtype<Z>, | ||
): Contract2<A, B, Z> | ||
export function Contract<Z>(Z: Runtype<Z>): Contract0<Z>; | ||
export function Contract<A, Z>(A: Runtype<A>, Z: Runtype<Z>): Contract1<A, Z>; | ||
export function Contract<A, B, Z>(A: Runtype<A>, B: Runtype<B>, Z: Runtype<Z>): Contract2<A, B, Z>; | ||
export function Contract<A, B, C, Z>( | ||
@@ -95,3 +72,3 @@ A: Runtype<A>, | ||
Z: Runtype<Z>, | ||
): Contract3<A, B, C, Z> | ||
): Contract3<A, B, C, Z>; | ||
export function Contract<A, B, C, D, Z>( | ||
@@ -103,3 +80,3 @@ A: Runtype<A>, | ||
Z: Runtype<Z>, | ||
): Contract4<A, B, C, D, Z> | ||
): Contract4<A, B, C, D, Z>; | ||
export function Contract<A, B, C, D, E, Z>( | ||
@@ -112,3 +89,3 @@ A: Runtype<A>, | ||
Z: Runtype<Z>, | ||
): Contract5<A, B, C, D, E, Z> | ||
): Contract5<A, B, C, D, E, Z>; | ||
export function Contract<A, B, C, D, E, F, Z>( | ||
@@ -122,3 +99,3 @@ A: Runtype<A>, | ||
Z: Runtype<Z>, | ||
): Contract6<A, B, C, D, E, F, Z> | ||
): Contract6<A, B, C, D, E, F, Z>; | ||
export function Contract<A, B, C, D, E, F, G, Z>( | ||
@@ -133,3 +110,3 @@ A: Runtype<A>, | ||
Z: Runtype<Z>, | ||
): Contract7<A, B, C, D, E, F, G, Z> | ||
): Contract7<A, B, C, D, E, F, G, Z>; | ||
export function Contract<A, B, C, D, E, F, G, H, Z>( | ||
@@ -145,3 +122,3 @@ A: Runtype<A>, | ||
Z: Runtype<Z>, | ||
): Contract8<A, B, C, D, E, F, G, H, Z> | ||
): Contract8<A, B, C, D, E, F, G, H, Z>; | ||
export function Contract<A, B, C, D, E, F, G, H, I, Z>( | ||
@@ -158,3 +135,3 @@ A: Runtype<A>, | ||
Z: Runtype<Z>, | ||
): Contract9<A, B, C, D, E, F, G, H, I, Z> | ||
): Contract9<A, B, C, D, E, F, G, H, I, Z>; | ||
export function Contract<A, B, C, D, E, F, G, H, I, J, Z>( | ||
@@ -172,16 +149,17 @@ A: Runtype<A>, | ||
Z: Runtype<Z>, | ||
): Contract10<A, B, C, D, E, F, G, H, I, J, Z> | ||
): Contract10<A, B, C, D, E, F, G, H, I, J, Z>; | ||
export function Contract(...runtypes: Runtype[]) { | ||
const lastIndex = runtypes.length - 1 | ||
const argTypes = runtypes.slice(0, lastIndex) | ||
const returnType = runtypes[lastIndex] | ||
const lastIndex = runtypes.length - 1; | ||
const argTypes = runtypes.slice(0, lastIndex); | ||
const returnType = runtypes[lastIndex]; | ||
return { | ||
enforce: (f: (...args: any[]) => any) => (...args: any[]) => { | ||
if (args.length < argTypes.length) | ||
throw validationError(`Expected ${argTypes.length} arguments but only received ${args.length}`) | ||
for (let i = 0; i < argTypes.length; i++) | ||
argTypes[i].check(args[i]) | ||
return returnType.check(f(...args)) | ||
} | ||
} | ||
throw validationError( | ||
`Expected ${argTypes.length} arguments but only received ${args.length}`, | ||
); | ||
for (let i = 0; i < argTypes.length; i++) argTypes[i].check(args[i]); | ||
return returnType.check(f(...args)); | ||
}, | ||
}; | ||
} |
@@ -1,8 +0,19 @@ | ||
import { Boolean, Number, String, Literal, Array, Tuple, Record, Dictionary, Union, Static } from '../index' | ||
import { | ||
Boolean, | ||
Number, | ||
String, | ||
Literal, | ||
Array, | ||
Tuple, | ||
Record, | ||
Dictionary, | ||
Union, | ||
Static, | ||
} from '../index'; | ||
const NonNegative = Number.withConstraint(n => n >= 0) | ||
type NonNegative = Static<typeof NonNegative> // = number | ||
const NonNegative = Number.withConstraint(n => n >= 0); | ||
type NonNegative = Static<typeof NonNegative>; // = number | ||
const Vector = Tuple(Number, Number, Number) | ||
type Vector = Static<typeof Vector> // = [number, number, number] | ||
const Vector = Tuple(Number, Number, Number); | ||
type Vector = Static<typeof Vector>; // = [number, number, number] | ||
@@ -13,4 +24,6 @@ const Asteroid = Record({ | ||
mass: NonNegative, | ||
}) | ||
type Asteroid = Static<typeof Asteroid> /* = { | ||
}); | ||
type Asteroid = Static< | ||
typeof Asteroid | ||
>; /* = { | ||
type: 'asteroid'; | ||
@@ -27,4 +40,6 @@ location: Vector; | ||
habitable: Boolean, | ||
}) | ||
type Planet = Static<typeof Planet> /* = { | ||
}); | ||
type Planet = Static< | ||
typeof Planet | ||
>; /* = { | ||
type: 'planet'; | ||
@@ -42,4 +57,4 @@ location: Vector; | ||
Literal('ensign'), | ||
) | ||
type Rank = Static<typeof Rank> // = 'captain' | 'first mate' | 'officer' | 'ensign' | ||
); | ||
type Rank = Static<typeof Rank>; // = 'captain' | 'first mate' | 'officer' | 'ensign' | ||
@@ -51,4 +66,6 @@ const CrewMember = Record({ | ||
home: Planet, | ||
}) | ||
type CrewMember = Static<typeof CrewMember> /* = { | ||
}); | ||
type CrewMember = Static< | ||
typeof CrewMember | ||
>; /* = { | ||
name: string; | ||
@@ -66,4 +83,6 @@ age: NonNegative; | ||
crew: Array(CrewMember), | ||
}) | ||
type Ship = Static<typeof Ship> /* = { | ||
}); | ||
type Ship = Static< | ||
typeof Ship | ||
>; /* = { | ||
type: 'ship'; | ||
@@ -76,6 +95,6 @@ location: Vector; | ||
const Fleet = Dictionary(Ship, 'number') | ||
type Fleet = Static<typeof Fleet> // = { [_: number]: Ship } | ||
const Fleet = Dictionary(Ship, 'number'); | ||
type Fleet = Static<typeof Fleet>; // = { [_: number]: Ship } | ||
const SpaceObject = Union(Asteroid, Planet, Ship) | ||
type SpaceObject = Static<typeof SpaceObject> // = Asteroid | Planet | Ship | ||
const SpaceObject = Union(Asteroid, Planet, Ship); | ||
type SpaceObject = Static<typeof SpaceObject>; // = Asteroid | Planet | Ship |
@@ -1,2 +0,2 @@ | ||
import { Static, Union, Literal } from '../index' | ||
import { Static, Union, Literal } from '../index'; | ||
@@ -12,12 +12,12 @@ // Define the runtype | ||
Literal('Saturday'), | ||
) | ||
); | ||
// Extract the static type | ||
type Day = Static<typeof Day> // = 'Sunday' | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday' | ||
type Day = Static<typeof Day>; // = 'Sunday' | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday' | ||
// Extract enumerated literal values | ||
const days: Day[] = Day.alternatives.map(lit => lit.value) | ||
const days: Day[] = Day.alternatives.map(lit => lit.value); | ||
for (const day of days) { | ||
console.log(`Good morning, it's ${day}!`) | ||
console.log(`Good morning, it's ${day}!`); | ||
} |
import { | ||
Runtype, | ||
Static, | ||
Always, always, | ||
Always, | ||
always, | ||
Never, | ||
@@ -17,5 +18,8 @@ Undefined, | ||
Partial, | ||
Tuple, Tuple2, | ||
Union, Union2, | ||
Intersect, Intersect2, | ||
Tuple, | ||
Tuple2, | ||
Union, | ||
Union2, | ||
Intersect, | ||
Intersect2, | ||
Function, | ||
@@ -27,12 +31,12 @@ Lazy, | ||
InstanceOf, | ||
} from './index' | ||
} from './index'; | ||
import { Constructor } from "./types/instanceof" | ||
import { Constructor } from './types/instanceof'; | ||
const boolTuple = Tuple(Boolean, Boolean, Boolean) | ||
const record1 = Record({ Boolean, Number }) | ||
const union1 = Union(Literal(3), String, boolTuple, record1) | ||
const boolTuple = Tuple(Boolean, Boolean, Boolean); | ||
const record1 = Record({ Boolean, Number }); | ||
const union1 = Union(Literal(3), String, boolTuple, record1); | ||
type Person = { name: string, likes: Person[] } | ||
const Person: Runtype<Person> = Lazy(() => Record({ name: String, likes: Array(Person) })) | ||
type Person = { name: string; likes: Person[] }; | ||
const Person: Runtype<Person> = Lazy(() => Record({ name: String, likes: Array(Person) })); | ||
@@ -71,4 +75,7 @@ class SomeClass { | ||
ArrayNumber: Array(Number), | ||
CustomArray: Array(Number).withConstraint(x => x.length > 3, {tag: 'lenght', min:3}), | ||
CustomArrayWithMessage: Array(Number).withConstraint(x => x.length > 3 || `Length array is not greater 3`, {tag: 'lenght', min:3}), | ||
CustomArray: Array(Number).withConstraint(x => x.length > 3, { tag: 'lenght', min: 3 }), | ||
CustomArrayWithMessage: Array(Number).withConstraint( | ||
x => x.length > 3 || `Length array is not greater 3`, | ||
{ tag: 'lenght', min: 3 }, | ||
), | ||
Dictionary: Dictionary(String), | ||
@@ -79,12 +86,14 @@ NumberDictionary: Dictionary(String, 'number'), | ||
InstanceOfSomeOtherClass: InstanceOf(SomeOtherClass), | ||
DictionaryOfArraysOfSomeClass: Dictionary(Array(InstanceOf(SomeClass))) | ||
} | ||
DictionaryOfArraysOfSomeClass: Dictionary(Array(InstanceOf(SomeClass))), | ||
}; | ||
type RuntypeName = keyof typeof runtypes | ||
type RuntypeName = keyof typeof runtypes; | ||
const runtypeNames = Object.keys(runtypes) as RuntypeName[] | ||
const runtypeNames = Object.keys(runtypes) as RuntypeName[]; | ||
class Foo { x: 'blah' } // Should not be recognized as a Dictionary | ||
class Foo { | ||
x: 'blah'; | ||
} // Should not be recognized as a Dictionary | ||
const testValues: { value: always, passes: RuntypeName[] }[] = [ | ||
const testValues: { value: always; passes: RuntypeName[] }[] = [ | ||
{ value: undefined, passes: ['Undefined', 'Void'] }, | ||
@@ -114,26 +123,24 @@ { value: null, passes: ['Null', 'Void'] }, | ||
{ value: new SomeClass(42), passes: ['InstanceOfSomeClass'] }, | ||
{ value: {xxx: [new SomeClass(55)]}, passes: ['DictionaryOfArraysOfSomeClass'] } | ||
] | ||
{ value: { xxx: [new SomeClass(55)] }, passes: ['DictionaryOfArraysOfSomeClass'] }, | ||
]; | ||
for (const { value, passes } of testValues) { | ||
const valueName = value === undefined ? 'undefined' : JSON.stringify(value) | ||
const valueName = value === undefined ? 'undefined' : JSON.stringify(value); | ||
describe(valueName, () => { | ||
const shouldPass: { [_ in RuntypeName]?: boolean } = {} | ||
const shouldPass: { [_ in RuntypeName]?: boolean } = {}; | ||
shouldPass.Always = true | ||
shouldPass.Always = true; | ||
if (value !== undefined && value !== null) | ||
shouldPass.Empty = true | ||
if (value !== undefined && value !== null) shouldPass.Empty = true; | ||
for (const name of passes) | ||
shouldPass[name] = true | ||
for (const name of passes) shouldPass[name] = true; | ||
for (const name of runtypeNames) { | ||
if (shouldPass[name]) { | ||
it(` : ${name}`, () => assertAccepts(value, runtypes[name])) | ||
it(` : ${name}`, () => assertAccepts(value, runtypes[name])); | ||
} else { | ||
it(`~: ${name}`, () => assertRejects(value, runtypes[name])) | ||
it(`~: ${name}`, () => assertRejects(value, runtypes[name])); | ||
} | ||
} | ||
}) | ||
}); | ||
} | ||
@@ -143,234 +150,236 @@ | ||
it('0 args', () => { | ||
const f = () => 3 | ||
expect(Contract(Number).enforce(f)()).toBe(3) | ||
const f = () => 3; | ||
expect(Contract(Number).enforce(f)()).toBe(3); | ||
try { | ||
Contract(String).enforce(f as any)() | ||
fail('contract was violated but no exception was thrown') | ||
} catch (e) {/* success */} | ||
}) | ||
Contract(String).enforce(f as any)(); | ||
fail('contract was violated but no exception was thrown'); | ||
} catch (e) { | ||
/* success */ | ||
} | ||
}); | ||
it('1 arg', () => { | ||
const f = (x: string) => x.length | ||
expect(Contract(String, Number).enforce(f)('hel')).toBe(3) | ||
const f = (x: string) => x.length; | ||
expect(Contract(String, Number).enforce(f)('hel')).toBe(3); | ||
try { | ||
;(Contract(String, Number).enforce(f) as any)(3) | ||
fail('contract was violated but no exception was thrown') | ||
(Contract(String, Number).enforce(f) as any)(3); | ||
fail('contract was violated but no exception was thrown'); | ||
Contract(String, String).enforce(f as any)('hi'); | ||
fail('contract was violated but no exception was thrown'); | ||
} catch (e) { | ||
/* success */ | ||
} | ||
}); | ||
;(Contract(String, String).enforce(f as any))('hi') | ||
fail('contract was violated but no exception was thrown') | ||
} catch (e) {/* success */} | ||
}) | ||
it('2 args', () => { | ||
const f = (x: string, y: boolean) => y ? x.length : 4 | ||
expect(Contract(String, Boolean, Number).enforce(f)('hello', false)).toBe(4) | ||
const f = (x: string, y: boolean) => (y ? x.length : 4); | ||
expect(Contract(String, Boolean, Number).enforce(f)('hello', false)).toBe(4); | ||
try { | ||
;(Contract(String, Boolean, Number).enforce(f) as any)('hello') | ||
fail('contract was violated but no exception was thrown') | ||
(Contract(String, Boolean, Number).enforce(f) as any)('hello'); | ||
fail('contract was violated but no exception was thrown'); | ||
(Contract(String, Boolean, Number).enforce(f) as any)('hello', 3); | ||
fail('contract was violated but no exception was thrown'); | ||
} catch (e) { | ||
/* success */ | ||
} | ||
}); | ||
}); | ||
;(Contract(String, Boolean, Number).enforce(f) as any)('hello', 3) | ||
fail('contract was violated but no exception was thrown') | ||
} catch (e) {/* success */} | ||
}) | ||
}) | ||
describe('reflection', () => { | ||
const X = Literal('x') | ||
const Y = Literal('y') | ||
const X = Literal('x'); | ||
const Y = Literal('y'); | ||
it('always', () => { | ||
expectLiteralField(Always, 'tag', 'always') | ||
}) | ||
expectLiteralField(Always, 'tag', 'always'); | ||
}); | ||
it('never', () => { | ||
expectLiteralField(Never, 'tag', 'never') | ||
}) | ||
expectLiteralField(Never, 'tag', 'never'); | ||
}); | ||
it('void', () => { | ||
expectLiteralField(Void, 'tag', 'void') | ||
}) | ||
expectLiteralField(Void, 'tag', 'void'); | ||
}); | ||
it('boolean', () => { | ||
expectLiteralField(Boolean, 'tag', 'boolean') | ||
}) | ||
expectLiteralField(Boolean, 'tag', 'boolean'); | ||
}); | ||
it('number', () => { | ||
expectLiteralField(Number, 'tag', 'number') | ||
}) | ||
expectLiteralField(Number, 'tag', 'number'); | ||
}); | ||
it('string', () => { | ||
expectLiteralField(String, 'tag', 'string') | ||
}) | ||
expectLiteralField(String, 'tag', 'string'); | ||
}); | ||
it('literal', () => { | ||
expectLiteralField(X, 'tag', 'literal') | ||
expectLiteralField(X, 'value', 'x') | ||
}) | ||
expectLiteralField(X, 'tag', 'literal'); | ||
expectLiteralField(X, 'value', 'x'); | ||
}); | ||
it('array', () => { | ||
expectLiteralField(Array(X), 'tag', 'array') | ||
expectLiteralField(Array(X).element, 'tag', 'literal') | ||
expectLiteralField(Array(X).element, 'value', 'x') | ||
}) | ||
expectLiteralField(Array(X), 'tag', 'array'); | ||
expectLiteralField(Array(X).element, 'tag', 'literal'); | ||
expectLiteralField(Array(X).element, 'value', 'x'); | ||
}); | ||
it('tuple', () => { | ||
expectLiteralField(Tuple(X, X), 'tag', 'tuple') | ||
expect(Tuple(X, X).components.map(C => C.tag)).toEqual(['literal', 'literal']) | ||
expect(Tuple(X, X).components.map(C => C.value)).toEqual(['x', 'x']) | ||
}) | ||
expectLiteralField(Tuple(X, X), 'tag', 'tuple'); | ||
expect(Tuple(X, X).components.map(C => C.tag)).toEqual(['literal', 'literal']); | ||
expect(Tuple(X, X).components.map(C => C.value)).toEqual(['x', 'x']); | ||
}); | ||
it('string dictionary', () => { | ||
const Rec = Dictionary(Always) | ||
expectLiteralField(Rec, 'tag', 'dictionary') | ||
expectLiteralField(Rec, 'key', 'string') | ||
}) | ||
const Rec = Dictionary(Always); | ||
expectLiteralField(Rec, 'tag', 'dictionary'); | ||
expectLiteralField(Rec, 'key', 'string'); | ||
}); | ||
it('number dictionary', () => { | ||
const Rec = Dictionary(Always, 'number') | ||
expectLiteralField(Rec, 'tag', 'dictionary') | ||
expectLiteralField(Rec, 'key', 'number') | ||
}) | ||
const Rec = Dictionary(Always, 'number'); | ||
expectLiteralField(Rec, 'tag', 'dictionary'); | ||
expectLiteralField(Rec, 'key', 'number'); | ||
}); | ||
it('record', () => { | ||
const Rec = Record({ x: Number, y: Literal(3) }) | ||
expectLiteralField(Rec, 'tag', 'record') | ||
expectLiteralField(Rec.fields.x, 'tag', 'number') | ||
expectLiteralField(Rec.fields.y, 'tag', 'literal') | ||
expectLiteralField(Rec.fields.y, 'value', 3) | ||
}) | ||
const Rec = Record({ x: Number, y: Literal(3) }); | ||
expectLiteralField(Rec, 'tag', 'record'); | ||
expectLiteralField(Rec.fields.x, 'tag', 'number'); | ||
expectLiteralField(Rec.fields.y, 'tag', 'literal'); | ||
expectLiteralField(Rec.fields.y, 'value', 3); | ||
}); | ||
it('partial', () => { | ||
const Opt = Partial({ x: Number, y: Literal(3) }) | ||
expectLiteralField(Opt, 'tag', 'partial') | ||
expectLiteralField(Opt.fields.x, 'tag', 'number') | ||
expectLiteralField(Opt.fields.y, 'tag', 'literal') | ||
expectLiteralField(Opt.fields.y, 'value', 3) | ||
}) | ||
const Opt = Partial({ x: Number, y: Literal(3) }); | ||
expectLiteralField(Opt, 'tag', 'partial'); | ||
expectLiteralField(Opt.fields.x, 'tag', 'number'); | ||
expectLiteralField(Opt.fields.y, 'tag', 'literal'); | ||
expectLiteralField(Opt.fields.y, 'value', 3); | ||
}); | ||
it('union', () => { | ||
expectLiteralField(Union(X, Y), 'tag', 'union') | ||
expectLiteralField(Union(X, Y), 'tag', 'union') | ||
expect(Union(X, Y).alternatives.map(A => A.tag)).toEqual(['literal', 'literal']) | ||
expect(Union(X, Y).alternatives.map(A => A.value)).toEqual(['x', 'y']) | ||
}) | ||
expectLiteralField(Union(X, Y), 'tag', 'union'); | ||
expectLiteralField(Union(X, Y), 'tag', 'union'); | ||
expect(Union(X, Y).alternatives.map(A => A.tag)).toEqual(['literal', 'literal']); | ||
expect(Union(X, Y).alternatives.map(A => A.value)).toEqual(['x', 'y']); | ||
}); | ||
it('intersect', () => { | ||
expectLiteralField(Intersect(X, Y), 'tag', 'intersect') | ||
expectLiteralField(Intersect(X, Y), 'tag', 'intersect') | ||
expect(Intersect(X, Y).intersectees.map(A => A.tag)).toEqual(['literal', 'literal']) | ||
expect(Intersect(X, Y).intersectees.map(A => A.value)).toEqual(['x', 'y']) | ||
}) | ||
expectLiteralField(Intersect(X, Y), 'tag', 'intersect'); | ||
expectLiteralField(Intersect(X, Y), 'tag', 'intersect'); | ||
expect(Intersect(X, Y).intersectees.map(A => A.tag)).toEqual(['literal', 'literal']); | ||
expect(Intersect(X, Y).intersectees.map(A => A.value)).toEqual(['x', 'y']); | ||
}); | ||
it('function', () => { | ||
expectLiteralField(Function, 'tag', 'function') | ||
}) | ||
expectLiteralField(Function, 'tag', 'function'); | ||
}); | ||
it('lazy', () => { | ||
const L = Lazy(() => X) | ||
expectLiteralField(L, 'tag', 'literal') | ||
expectLiteralField(L, 'value', 'x') | ||
}) | ||
const L = Lazy(() => X); | ||
expectLiteralField(L, 'tag', 'literal'); | ||
expectLiteralField(L, 'value', 'x'); | ||
}); | ||
it('constraint', () => { | ||
const C = Number.withConstraint(n => n > 9) | ||
expectLiteralField(C, 'tag', 'constraint') | ||
expectLiteralField(C.underlying, 'tag', 'number') | ||
}) | ||
const C = Number.withConstraint(n => n > 9); | ||
expectLiteralField(C, 'tag', 'constraint'); | ||
expectLiteralField(C.underlying, 'tag', 'number'); | ||
}); | ||
it('instanceof', () => { | ||
class Test {} | ||
expectLiteralField(InstanceOf(Test), "tag", "instanceof") | ||
expectLiteralField(Dictionary(Array(InstanceOf(Test))), "tag", "dictionary") | ||
}) | ||
}) | ||
expectLiteralField(InstanceOf(Test), 'tag', 'instanceof'); | ||
expectLiteralField(Dictionary(Array(InstanceOf(Test))), 'tag', 'dictionary'); | ||
}); | ||
}); | ||
// Static tests of reflection | ||
;( | ||
( | ||
X: | ||
| Always | ||
| Never | ||
| Void | ||
| Boolean | ||
| Number | ||
| String | ||
| Literal<boolean | number | string> | ||
| Array<Reflect> | ||
| Record<{ [_ in string]: Reflect }> | ||
| Partial<{ [_ in string]: Reflect }> | ||
| Tuple2<Reflect, Reflect> | ||
| Union2<Reflect, Reflect> | ||
| Intersect2<Reflect, Reflect> | ||
| Function | ||
| Constraint<Reflect, any> | ||
| InstanceOf<Constructor> | ||
| Always | ||
| Never | ||
| Void | ||
| Boolean | ||
| Number | ||
| String | ||
| Literal<boolean | number | string> | ||
| Array<Reflect> | ||
| Record<{ [_ in string]: Reflect }> | ||
| Partial<{ [_ in string]: Reflect }> | ||
| Tuple2<Reflect, Reflect> | ||
| Union2<Reflect, Reflect> | ||
| Intersect2<Reflect, Reflect> | ||
| Function | ||
| Constraint<Reflect, any> | ||
| InstanceOf<Constructor>, | ||
): Reflect => { | ||
const check = <A>(X: Runtype<A>): A => X.check({}) | ||
const check = <A>(X: Runtype<A>): A => X.check({}); | ||
switch (X.tag) { | ||
case 'always': | ||
check<always>(X) | ||
break | ||
check<always>(X); | ||
break; | ||
case 'never': | ||
check<never>(X) | ||
break | ||
check<never>(X); | ||
break; | ||
case 'void': | ||
check<void>(X) | ||
break | ||
check<void>(X); | ||
break; | ||
case 'boolean': | ||
check<boolean>(X) | ||
break | ||
check<boolean>(X); | ||
break; | ||
case 'number': | ||
check<number>(X) | ||
break | ||
check<number>(X); | ||
break; | ||
case 'string': | ||
check<string>(X) | ||
break | ||
check<string>(X); | ||
break; | ||
case 'literal': | ||
check<typeof X.value>(X) | ||
break | ||
check<typeof X.value>(X); | ||
break; | ||
case 'array': | ||
check<(Static<typeof X.element>)[]>(X) | ||
break | ||
check<(Static<typeof X.element>)[]>(X); | ||
break; | ||
case 'record': | ||
check<{ [K in keyof typeof X.fields]: Static<typeof X.fields['K']> }>(X) | ||
break | ||
check<{ [K in keyof typeof X.fields]: Static<typeof X.fields['K']> }>(X); | ||
break; | ||
case 'partial': | ||
check<{ [K in keyof typeof X.fields]?: Static<typeof X.fields['K']> }>(X) | ||
break | ||
check<{ [K in keyof typeof X.fields]?: Static<typeof X.fields['K']> }>(X); | ||
break; | ||
case 'tuple': | ||
check<[Static<typeof X.components[0]>, Static<typeof X.components[1]>]>(X) | ||
break | ||
check<[Static<typeof X.components[0]>, Static<typeof X.components[1]>]>(X); | ||
break; | ||
case 'union': | ||
check<Static<typeof X.alternatives[0]> | Static<typeof X.alternatives[1]>>(X) | ||
break | ||
check<Static<typeof X.alternatives[0]> | Static<typeof X.alternatives[1]>>(X); | ||
break; | ||
case 'intersect': | ||
check<Static<typeof X.intersectees[0]> & Static<typeof X.intersectees[1]>>(X) | ||
break | ||
check<Static<typeof X.intersectees[0]> & Static<typeof X.intersectees[1]>>(X); | ||
break; | ||
case 'function': | ||
check<(...args: any[]) => any>(X) | ||
break | ||
check<(...args: any[]) => any>(X); | ||
break; | ||
case 'constraint': | ||
check<Static<typeof X.underlying>>(X) | ||
check<Static<typeof X.underlying>>(X); | ||
break; | ||
case 'instanceof': | ||
check<typeof X.ctor>(X) | ||
check<typeof X.ctor>(X); | ||
break; | ||
} | ||
return X | ||
} | ||
return X; | ||
}; | ||
function expectLiteralField<O, K extends keyof O, V extends O[K]>(o: O, k: K, v: V) { | ||
expect(o[k]).toBe(v) | ||
expect(o[k]).toBe(v); | ||
} | ||
function assertAccepts<A>(value: always, runtype: Runtype<A>) { | ||
const result = runtype.validate(value) | ||
if (result.success === false) | ||
fail(result.message) | ||
const result = runtype.validate(value); | ||
if (result.success === false) fail(result.message); | ||
} | ||
function assertRejects<A>(value: always, runtype: Runtype<A>) { | ||
const result = runtype.validate(value) | ||
if (result.success === true) | ||
fail('value passed validation even though it was not expected to') | ||
const result = runtype.validate(value); | ||
if (result.success === true) fail('value passed validation even though it was not expected to'); | ||
} |
@@ -1,22 +0,22 @@ | ||
export { Runtype, Static } from './runtype' | ||
export * from './reflect' | ||
export * from './result' | ||
export * from './contract' | ||
export * from './types/always' | ||
export * from './types/never' | ||
export * from './types/void' | ||
export { Literal, Undefined, Null } from './types/literal' | ||
export * from './types/boolean' | ||
export * from './types/number' | ||
export * from './types/string' | ||
export * from './types/array' | ||
export * from './types/tuple' | ||
export * from './types/record' | ||
export * from './types/partial' | ||
export * from './types/dictionary' | ||
export * from './types/union' | ||
export * from './types/intersect' | ||
export * from './types/function' | ||
export * from './types/lazy' | ||
export * from './types/constraint' | ||
export {InstanceOf } from "./types/instanceof" | ||
export { Runtype, Static } from './runtype'; | ||
export * from './reflect'; | ||
export * from './result'; | ||
export * from './contract'; | ||
export * from './types/always'; | ||
export * from './types/never'; | ||
export * from './types/void'; | ||
export { Literal, Undefined, Null } from './types/literal'; | ||
export * from './types/boolean'; | ||
export * from './types/number'; | ||
export * from './types/string'; | ||
export * from './types/array'; | ||
export * from './types/tuple'; | ||
export * from './types/record'; | ||
export * from './types/partial'; | ||
export * from './types/dictionary'; | ||
export * from './types/union'; | ||
export * from './types/intersect'; | ||
export * from './types/function'; | ||
export * from './types/lazy'; | ||
export * from './types/constraint'; | ||
export { InstanceOf } from './types/instanceof'; |
@@ -1,6 +0,6 @@ | ||
import { Runtype } from './runtype' | ||
import { always } from './types/always' | ||
import { LiteralBase } from './types/literal' | ||
import { ConstraintCheck } from './types/constraint' | ||
import { Constructor } from "./types/instanceof" | ||
import { Runtype } from './runtype'; | ||
import { always } from './types/always'; | ||
import { LiteralBase } from './types/literal'; | ||
import { ConstraintCheck } from './types/constraint'; | ||
import { Constructor } from './types/instanceof'; | ||
@@ -18,3 +18,5 @@ export type Reflect = | ||
| { tag: 'partial'; fields: { [_: string]: Reflect } } & Runtype<{ [_ in string]?: always }> | ||
| { tag: 'dictionary'; key: 'string' | 'number'; value: Reflect } & Runtype<{ [_: string]: always }> | ||
| { tag: 'dictionary'; key: 'string' | 'number'; value: Reflect } & Runtype<{ | ||
[_: string]: always; | ||
}> | ||
| { tag: 'tuple'; components: Reflect[] } & Runtype<[always]> | ||
@@ -24,3 +26,8 @@ | { tag: 'union'; alternatives: Reflect[] } & Runtype<always> | ||
| { tag: 'function' } & Runtype<(...args: any[]) => any> | ||
| { tag: 'constraint'; underlying: Reflect; constraint: ConstraintCheck<Runtype<always>>; args?: any } & Runtype<always> | ||
| { tag: 'instanceof', ctor: Constructor<always> } & Runtype<always> | ||
| { | ||
tag: 'constraint'; | ||
underlying: Reflect; | ||
constraint: ConstraintCheck<Runtype<always>>; | ||
args?: any; | ||
} & Runtype<always> | ||
| { tag: 'instanceof'; ctor: Constructor<always> } & Runtype<always>; |
@@ -8,3 +8,3 @@ /** | ||
*/ | ||
success: true | ||
success: true; | ||
@@ -14,4 +14,4 @@ /** | ||
*/ | ||
value: A | ||
} | ||
value: A; | ||
}; | ||
@@ -25,3 +25,3 @@ /** | ||
*/ | ||
success: false | ||
success: false; | ||
@@ -31,4 +31,4 @@ /** | ||
*/ | ||
message: string | ||
} | ||
message: string; | ||
}; | ||
@@ -38,2 +38,2 @@ /** | ||
*/ | ||
export type Result<A> = Success<A> | Failure | ||
export type Result<A> = Success<A> | Failure; |
@@ -1,4 +0,4 @@ | ||
import { Result, Union, Union2, Intersect, Intersect2, Constraint, ConstraintCheck } from './index' | ||
import { Reflect } from './reflect' | ||
import show from './show' | ||
import { Result, Union, Union2, Intersect, Intersect2, Constraint, ConstraintCheck } from './index'; | ||
import { Reflect } from './reflect'; | ||
import show from './show'; | ||
@@ -13,3 +13,3 @@ /** | ||
*/ | ||
check(x: any): A | ||
check(x: any): A; | ||
@@ -20,3 +20,3 @@ /** | ||
*/ | ||
validate(x: any): Result<A> | ||
validate(x: any): Result<A>; | ||
@@ -26,3 +26,3 @@ /** | ||
*/ | ||
guard(x: any): x is A | ||
guard(x: any): x is A; | ||
@@ -32,3 +32,3 @@ /** | ||
*/ | ||
Or<B extends Runtype>(B: B): Union2<this, B> | ||
Or<B extends Runtype>(B: B): Union2<this, B>; | ||
@@ -38,3 +38,3 @@ /** | ||
*/ | ||
And<B extends Runtype>(B: B): Intersect2<this, B> | ||
And<B extends Runtype>(B: B): Intersect2<this, B>; | ||
@@ -47,3 +47,3 @@ /** | ||
*/ | ||
withConstraint<K>(constraint: ConstraintCheck<this>, args?: K): Constraint<this, K> | ||
withConstraint<K>(constraint: ConstraintCheck<this>, args?: K): Constraint<this, K>; | ||
@@ -53,5 +53,5 @@ /** | ||
*/ | ||
reflect: Reflect | ||
reflect: Reflect; | ||
/* @internal */ _falseWitness: A | ||
/* @internal */ _falseWitness: A; | ||
} | ||
@@ -62,23 +62,22 @@ | ||
*/ | ||
export type Static<A extends Runtype> = A['_falseWitness'] | ||
export type Static<A extends Runtype> = A['_falseWitness']; | ||
export function create<A extends Runtype>(check: (x: {}) => Static<A>, A: any): A { | ||
A.check = check; | ||
A.validate = validate; | ||
A.guard = guard; | ||
A.Or = Or; | ||
A.And = And; | ||
A.withConstraint = withConstraint; | ||
A.reflect = A; | ||
A.toString = () => `Runtype<${show(A)}>`; | ||
A.check = check | ||
A.validate = validate | ||
A.guard = guard | ||
A.Or = Or | ||
A.And = And | ||
A.withConstraint = withConstraint | ||
A.reflect = A | ||
A.toString = () => `Runtype<${show(A)}>` | ||
return A; | ||
return A | ||
function validate(value: any): Result<A> { | ||
try { | ||
check(value) | ||
return { success: true, value } | ||
check(value); | ||
return { success: true, value }; | ||
} catch ({ message }) { | ||
return { success: false, message } | ||
return { success: false, message }; | ||
} | ||
@@ -88,15 +87,15 @@ } | ||
function guard(x: any): x is A { | ||
return validate(x).success | ||
return validate(x).success; | ||
} | ||
function Or<B extends Runtype>(B: B): Union2<A, B> { | ||
return Union(A, B) | ||
return Union(A, B); | ||
} | ||
function And<B extends Runtype>(B: B): Intersect2<A, B> { | ||
return Intersect(A, B) | ||
return Intersect(A, B); | ||
} | ||
function withConstraint<K>(constraint: ConstraintCheck<A>, args?: K): Constraint<A, K> { | ||
return Constraint(A, constraint, args) | ||
return Constraint(A, constraint, args); | ||
} | ||
@@ -107,3 +106,3 @@ } | ||
constructor(message: string) { | ||
super(message) | ||
super(message); | ||
} | ||
@@ -113,3 +112,3 @@ } | ||
export function validationError(message: string) { | ||
return new ValidationError(message) | ||
return new ValidationError(message); | ||
} |
@@ -22,4 +22,4 @@ import { | ||
Reflect, | ||
} from './index' | ||
import show from './show' | ||
} from './index'; | ||
import show from './show'; | ||
@@ -46,24 +46,9 @@ class TestClass {} | ||
[Partial({}), '{}'], | ||
[InstanceOf(TestClass), "InstanceOf<TestClass>"], | ||
[Array(InstanceOf(TestClass)), "InstanceOf<TestClass>[]"], | ||
[ | ||
Record({ x: String, y: Array(Boolean) }), | ||
'{ x: string; y: boolean[]; }' | ||
], | ||
[ | ||
Partial({ x: String, y: Array(Boolean) }), | ||
'{ x?: string; y?: boolean[]; }' | ||
], | ||
[ | ||
Tuple(Boolean, Number), | ||
'[boolean, number]' | ||
], | ||
[ | ||
Union(Boolean, Number), | ||
'boolean | number' | ||
], | ||
[ | ||
Intersect(Boolean, Number), | ||
'boolean & number' | ||
], | ||
[InstanceOf(TestClass), 'InstanceOf<TestClass>'], | ||
[Array(InstanceOf(TestClass)), 'InstanceOf<TestClass>[]'], | ||
[Record({ x: String, y: Array(Boolean) }), '{ x: string; y: boolean[]; }'], | ||
[Partial({ x: String, y: Array(Boolean) }), '{ x?: string; y?: boolean[]; }'], | ||
[Tuple(Boolean, Number), '[boolean, number]'], | ||
[Union(Boolean, Number), 'boolean | number'], | ||
[Intersect(Boolean, Number), 'boolean & number'], | ||
[Function, 'function'], | ||
@@ -74,23 +59,13 @@ [Lazy(() => Boolean), 'boolean'], | ||
// Parenthesization | ||
[ | ||
Boolean.And(Number.Or(String)), | ||
'boolean & (number | string)' | ||
], | ||
[ | ||
Boolean.Or(Number.And(String)), | ||
'boolean | (number & string)' | ||
], | ||
[ | ||
Boolean.Or(Record({ x: String, y: Number })), | ||
'boolean | { x: string; y: number; }' | ||
] | ||
] | ||
[Boolean.And(Number.Or(String)), 'boolean & (number | string)'], | ||
[Boolean.Or(Number.And(String)), 'boolean | (number & string)'], | ||
[Boolean.Or(Record({ x: String, y: Number })), 'boolean | { x: string; y: number; }'], | ||
]; | ||
for (const [T, expected] of cases) { | ||
const s = show(T) | ||
const s = show(T); | ||
it(s, () => { | ||
expect(s).toBe(expected) | ||
expect(T.toString()).toBe(`Runtype<${s}>`) | ||
}) | ||
expect(s).toBe(expected); | ||
expect(T.toString()).toBe(`Runtype<${s}>`); | ||
}); | ||
} | ||
@@ -1,7 +0,6 @@ | ||
import { Reflect } from './index' | ||
import { Reflect } from './index'; | ||
const show = (needsParens: boolean) => (refl: Reflect): string => { | ||
const parenthesize = (s: string) => (needsParens ? `(${s})` : s); | ||
const parenthesize = (s: string) => needsParens ? `(${s})` : s | ||
switch (refl.tag) { | ||
@@ -16,43 +15,39 @@ // Primitive types | ||
case 'function': | ||
return refl.tag | ||
return refl.tag; | ||
// Complex types | ||
case 'literal': { | ||
const { value } = refl | ||
return typeof value === 'string' | ||
? `"${value}"` | ||
: String(value) | ||
const { value } = refl; | ||
return typeof value === 'string' ? `"${value}"` : String(value); | ||
} | ||
case 'array': | ||
return `${show(true)(refl.element)}[]` | ||
return `${show(true)(refl.element)}[]`; | ||
case 'dictionary': | ||
return `{ [_: ${refl.key}]: ${show(false)(refl.value)} }` | ||
return `{ [_: ${refl.key}]: ${show(false)(refl.value)} }`; | ||
case 'record': { | ||
const keys = Object.keys(refl.fields) | ||
return keys.length ? `{ ${keys | ||
.map(k => `${k}: ${show(false)(refl.fields[k])};`) | ||
.join(' ') | ||
} }` : '{}' | ||
const keys = Object.keys(refl.fields); | ||
return keys.length | ||
? `{ ${keys.map(k => `${k}: ${show(false)(refl.fields[k])};`).join(' ')} }` | ||
: '{}'; | ||
} | ||
case 'partial': { | ||
const keys = Object.keys(refl.fields) | ||
return keys.length ? `{ ${keys | ||
.map(k => `${k}?: ${show(false)(refl.fields[k])};`) | ||
.join(' ') | ||
} }` : '{}' | ||
const keys = Object.keys(refl.fields); | ||
return keys.length | ||
? `{ ${keys.map(k => `${k}?: ${show(false)(refl.fields[k])};`).join(' ')} }` | ||
: '{}'; | ||
} | ||
case 'tuple': | ||
return `[${refl.components.map(show(false)).join(', ')}]` | ||
return `[${refl.components.map(show(false)).join(', ')}]`; | ||
case 'union': | ||
return parenthesize(`${refl.alternatives.map(show(true)).join(' | ')}`) | ||
return parenthesize(`${refl.alternatives.map(show(true)).join(' | ')}`); | ||
case 'intersect': | ||
return parenthesize(`${refl.intersectees.map(show(true)).join(' & ')}`) | ||
return parenthesize(`${refl.intersectees.map(show(true)).join(' & ')}`); | ||
case 'constraint': | ||
return show(needsParens)(refl.underlying) | ||
return show(needsParens)(refl.underlying); | ||
case 'instanceof': | ||
const name = (refl.ctor as any).name | ||
return `InstanceOf<${(name)}>` | ||
const name = (refl.ctor as any).name; | ||
return `InstanceOf<${name}>`; | ||
} | ||
} | ||
}; | ||
export default show(false) | ||
export default show(false); |
@@ -1,6 +0,8 @@ | ||
import { Runtype, create } from '../runtype' | ||
import { Runtype, create } from '../runtype'; | ||
export type always = {} | void | null | ||
export type always = {} | void | null; | ||
export interface Always extends Runtype<always> { tag: 'always' } | ||
export interface Always extends Runtype<always> { | ||
tag: 'always'; | ||
} | ||
@@ -10,3 +12,2 @@ /** | ||
*/ | ||
export const Always = create<Always>(x => x, { tag: 'always' }) | ||
export const Always = create<Always>(x => x, { tag: 'always' }); |
@@ -1,6 +0,6 @@ | ||
import { Runtype, Static, create, validationError } from '../runtype' | ||
import { Runtype, Static, create, validationError } from '../runtype'; | ||
interface Arr<E extends Runtype> extends Runtype<Static<E>[]> { | ||
tag: 'array' | ||
element: E | ||
tag: 'array'; | ||
element: E; | ||
} | ||
@@ -12,11 +12,12 @@ | ||
function Arr<E extends Runtype>(element: E): Arr<E> { | ||
return create<Arr<E>>(xs => { | ||
if (!Array.isArray(xs)) | ||
throw validationError(`Expected array but was ${typeof xs}`) | ||
for (const x of xs) | ||
element.check(x) | ||
return xs | ||
}, { tag: 'array', element }) | ||
return create<Arr<E>>( | ||
xs => { | ||
if (!Array.isArray(xs)) throw validationError(`Expected array but was ${typeof xs}`); | ||
for (const x of xs) element.check(x); | ||
return xs; | ||
}, | ||
{ tag: 'array', element }, | ||
); | ||
} | ||
export { Arr as Array } | ||
export { Arr as Array }; |
@@ -1,4 +0,6 @@ | ||
import { Runtype, create, validationError } from '../runtype' | ||
import { Runtype, create, validationError } from '../runtype'; | ||
export interface Boolean extends Runtype<boolean> { tag: 'boolean' } | ||
export interface Boolean extends Runtype<boolean> { | ||
tag: 'boolean'; | ||
} | ||
@@ -8,6 +10,8 @@ /** | ||
*/ | ||
export const Boolean = create<Boolean>(x => { | ||
if (typeof x !== 'boolean') | ||
throw validationError(`Expected boolean but was ${typeof x}`) | ||
return x | ||
}, { tag: 'boolean' }) | ||
export const Boolean = create<Boolean>( | ||
x => { | ||
if (typeof x !== 'boolean') throw validationError(`Expected boolean but was ${typeof x}`); | ||
return x; | ||
}, | ||
{ tag: 'boolean' }, | ||
); |
@@ -1,25 +0,30 @@ | ||
import { Runtype, Static, create, validationError } from '../runtype' | ||
import { String } from './string' | ||
import { Runtype, Static, create, validationError } from '../runtype'; | ||
import { String } from './string'; | ||
export type ConstraintCheck<A extends Runtype> = (x: Static<A>) => boolean | string | ||
export type ConstraintCheck<A extends Runtype> = (x: Static<A>) => boolean | string; | ||
export interface Constraint<A extends Runtype, K> extends Runtype<Static<A>> { | ||
tag: 'constraint' | ||
underlying: A, | ||
tag: 'constraint'; | ||
underlying: A; | ||
// See: https://github.com/Microsoft/TypeScript/issues/19746 for why this isn't just | ||
// `constraint: ConstraintCheck<A>` | ||
constraint(x: Static<A>): boolean | string, | ||
args?: K | ||
constraint(x: Static<A>): boolean | string; | ||
args?: K; | ||
} | ||
export function Constraint<A extends Runtype, K>(underlying: A, constraint: ConstraintCheck<A>, args?: K) { | ||
return create<Constraint<A, K>>(x => { | ||
const typed = underlying.check(x) | ||
const result = constraint(typed) | ||
if (String.guard(result)) | ||
throw validationError(result) | ||
else if (!result) | ||
throw validationError('Failed constraint check') | ||
return typed | ||
}, { tag: 'constraint', underlying, args, constraint }) | ||
export function Constraint<A extends Runtype, K>( | ||
underlying: A, | ||
constraint: ConstraintCheck<A>, | ||
args?: K, | ||
) { | ||
return create<Constraint<A, K>>( | ||
x => { | ||
const typed = underlying.check(x); | ||
const result = constraint(typed); | ||
if (String.guard(result)) throw validationError(result); | ||
else if (!result) throw validationError('Failed constraint check'); | ||
return typed; | ||
}, | ||
{ tag: 'constraint', underlying, args, constraint }, | ||
); | ||
} |
@@ -1,14 +0,14 @@ | ||
import { Runtype, create, Static, validationError } from '../runtype' | ||
import { Record } from './record' | ||
import { Runtype, create, Static, validationError } from '../runtype'; | ||
import { Record } from './record'; | ||
export interface StringDictionary<V extends Runtype> extends Runtype<{ [_: string]: Static<V> }> { | ||
tag: 'dictionary' | ||
key: 'string' | ||
value: V | ||
tag: 'dictionary'; | ||
key: 'string'; | ||
value: V; | ||
} | ||
export interface NumberDictionary<V extends Runtype> extends Runtype<{ [_: number]: Static<V> }> { | ||
tag: 'dictionary' | ||
key: 'number' | ||
value: V | ||
tag: 'dictionary'; | ||
key: 'number'; | ||
value: V; | ||
} | ||
@@ -19,29 +19,29 @@ | ||
*/ | ||
export function Dictionary<V extends Runtype>(value: V, key?: 'string'): StringDictionary<V> | ||
export function Dictionary<V extends Runtype>(value: V, key?: 'number'): NumberDictionary<V> | ||
export function Dictionary<V extends Runtype>(value: V, key?: 'string'): StringDictionary<V>; | ||
export function Dictionary<V extends Runtype>(value: V, key?: 'number'): NumberDictionary<V>; | ||
export function Dictionary<V extends Runtype>(value: V, key = 'string'): any { | ||
return create<Runtype>(x => { | ||
Record({}).check(x) | ||
return create<Runtype>( | ||
x => { | ||
Record({}).check(x); | ||
if (typeof x !== 'object') | ||
throw validationError(`Expected an object but was ${typeof x}`) | ||
if (typeof x !== 'object') throw validationError(`Expected an object but was ${typeof x}`); | ||
if (Object.getPrototypeOf(x) !== Object.prototype) { | ||
if (!Array.isArray(x)) | ||
throw validationError(`Expected simple object but was complex`) | ||
else if (key === 'string') | ||
throw validationError(`Expected dictionary but was array`) | ||
} | ||
if (Object.getPrototypeOf(x) !== Object.prototype) { | ||
if (!Array.isArray(x)) throw validationError(`Expected simple object but was complex`); | ||
else if (key === 'string') throw validationError(`Expected dictionary but was array`); | ||
} | ||
for (const k in x) { | ||
// Object keys are always strings | ||
if (key === 'number') { | ||
if (isNaN(+k)) | ||
throw validationError(`Expected dictionary key to be a number but was string`) | ||
for (const k in x) { | ||
// Object keys are always strings | ||
if (key === 'number') { | ||
if (isNaN(+k)) | ||
throw validationError(`Expected dictionary key to be a number but was string`); | ||
} | ||
value.check((x as any)[k]); | ||
} | ||
value.check((x as any)[k]) | ||
} | ||
return x | ||
}, { tag: 'dictionary', key, value }) | ||
return x; | ||
}, | ||
{ tag: 'dictionary', key, value }, | ||
); | ||
} |
@@ -1,4 +0,6 @@ | ||
import { Runtype, create, validationError } from '../runtype' | ||
import { Runtype, create, validationError } from '../runtype'; | ||
export interface Function extends Runtype<(...args: any[]) => any> { tag: 'function' } | ||
export interface Function extends Runtype<(...args: any[]) => any> { | ||
tag: 'function'; | ||
} | ||
@@ -8,6 +10,8 @@ /** | ||
*/ | ||
export const Function = create<Function>(x => { | ||
if (typeof x !== 'function') | ||
throw validationError(`Expected a function but was ${typeof x}`) | ||
return x | ||
}, { tag: 'function' }) | ||
export const Function = create<Function>( | ||
x => { | ||
if (typeof x !== 'function') throw validationError(`Expected a function but was ${typeof x}`); | ||
return x; | ||
}, | ||
{ tag: 'function' }, | ||
); |
@@ -1,2 +0,2 @@ | ||
import { Runtype, create, validationError } from "../runtype"; | ||
import { Runtype, create, validationError } from '../runtype'; | ||
@@ -8,7 +8,6 @@ export interface Constructor<V> { | ||
export interface InstanceOf<V> extends Runtype<V> { | ||
tag: "instanceof"; | ||
tag: 'instanceof'; | ||
ctor: Constructor<V>; | ||
} | ||
export function InstanceOf<V>(ctor: Constructor<V>) { | ||
@@ -18,10 +17,8 @@ return create<InstanceOf<V>>( | ||
if (!(x instanceof ctor)) { | ||
throw validationError( | ||
`Expected a ${(ctor as any).name} but was ${typeof x}` | ||
); | ||
throw validationError(`Expected a ${(ctor as any).name} but was ${typeof x}`); | ||
} | ||
return x as V; | ||
}, | ||
{ tag: "instanceof", ctor: ctor } | ||
{ tag: 'instanceof', ctor: ctor }, | ||
); | ||
} |
@@ -1,90 +0,137 @@ | ||
import { Runtype, Static, create } from '../runtype' | ||
import { Runtype, Static, create } from '../runtype'; | ||
export interface Intersect1< | ||
A extends Runtype, | ||
> extends Runtype< | ||
Static<A> | ||
> { | ||
tag: 'intersect' | ||
intersectees: [A] | ||
export interface Intersect1<A extends Runtype> extends Runtype<Static<A>> { | ||
tag: 'intersect'; | ||
intersectees: [A]; | ||
} | ||
export interface Intersect2< | ||
A extends Runtype, B extends Runtype, | ||
> extends Runtype< | ||
Static<A> & Static<B> | ||
> { | ||
tag: 'intersect' | ||
intersectees: [A, B] | ||
export interface Intersect2<A extends Runtype, B extends Runtype> | ||
extends Runtype<Static<A> & Static<B>> { | ||
tag: 'intersect'; | ||
intersectees: [A, B]; | ||
} | ||
export interface Intersect3< | ||
A extends Runtype, B extends Runtype, C extends Runtype, | ||
> extends Runtype< | ||
Static<A> & Static<B> & Static<C> | ||
> { | ||
tag: 'intersect' | ||
intersectees: [A, B, C] | ||
export interface Intersect3<A extends Runtype, B extends Runtype, C extends Runtype> | ||
extends Runtype<Static<A> & Static<B> & Static<C>> { | ||
tag: 'intersect'; | ||
intersectees: [A, B, C]; | ||
} | ||
export interface Intersect4< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, | ||
> extends Runtype< | ||
Static<A> & Static<B> & Static<C> & Static<D> | ||
> { | ||
tag: 'intersect' | ||
intersectees: [A, B, C, D] | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype | ||
> extends Runtype<Static<A> & Static<B> & Static<C> & Static<D>> { | ||
tag: 'intersect'; | ||
intersectees: [A, B, C, D]; | ||
} | ||
export interface Intersect5< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, | ||
> extends Runtype< | ||
Static<A> & Static<B> & Static<C> & Static<D> & Static<E> | ||
> { | ||
tag: 'intersect' | ||
intersectees: [A, B, C, D, E] | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype | ||
> extends Runtype<Static<A> & Static<B> & Static<C> & Static<D> & Static<E>> { | ||
tag: 'intersect'; | ||
intersectees: [A, B, C, D, E]; | ||
} | ||
export interface Intersect6< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, | ||
> extends Runtype< | ||
Static<A> & Static<B> & Static<C> & Static<D> & Static<E> & Static<F> | ||
> { | ||
tag: 'intersect' | ||
intersectees: [A, B, C, D, E, F] | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype | ||
> extends Runtype<Static<A> & Static<B> & Static<C> & Static<D> & Static<E> & Static<F>> { | ||
tag: 'intersect'; | ||
intersectees: [A, B, C, D, E, F]; | ||
} | ||
export interface Intersect7< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, | ||
> extends Runtype< | ||
Static<A> & Static<B> & Static<C> & Static<D> & Static<E> & Static<F> & Static<G> | ||
> { | ||
tag: 'intersect' | ||
intersectees: [A, B, C, D, E, F, G] | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype | ||
> | ||
extends Runtype< | ||
Static<A> & Static<B> & Static<C> & Static<D> & Static<E> & Static<F> & Static<G> | ||
> { | ||
tag: 'intersect'; | ||
intersectees: [A, B, C, D, E, F, G]; | ||
} | ||
export interface Intersect8< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, | ||
> extends Runtype< | ||
Static<A> & Static<B> & Static<C> & Static<D> & Static<E> & Static<F> & Static<G> & Static<H> | ||
> { | ||
tag: 'intersect' | ||
intersectees: [A, B, C, D, E, F, G, H] | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype, | ||
H extends Runtype | ||
> | ||
extends Runtype< | ||
Static<A> & Static<B> & Static<C> & Static<D> & Static<E> & Static<F> & Static<G> & Static<H> | ||
> { | ||
tag: 'intersect'; | ||
intersectees: [A, B, C, D, E, F, G, H]; | ||
} | ||
export interface Intersect9< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype, | ||
> extends Runtype< | ||
Static<A> & Static<B> & Static<C> & Static<D> & Static<E> & Static<F> & Static<G> & Static<H> & Static<I> | ||
> { | ||
tag: 'intersect' | ||
intersectees: [A, B, C, D, E, F, G, H, I] | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype, | ||
H extends Runtype, | ||
I extends Runtype | ||
> | ||
extends Runtype< | ||
Static<A> & | ||
Static<B> & | ||
Static<C> & | ||
Static<D> & | ||
Static<E> & | ||
Static<F> & | ||
Static<G> & | ||
Static<H> & | ||
Static<I> | ||
> { | ||
tag: 'intersect'; | ||
intersectees: [A, B, C, D, E, F, G, H, I]; | ||
} | ||
export interface Intersect10< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype, J extends Runtype, | ||
> extends Runtype< | ||
Static<A> & Static<B> & Static<C> & Static<D> & Static<E> & Static<F> & Static<G> & Static<H> & Static<I> & Static<J> | ||
> { | ||
tag: 'intersect' | ||
intersectees: [A, B, C, D, E, F, G, H, I, J] | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype, | ||
H extends Runtype, | ||
I extends Runtype, | ||
J extends Runtype | ||
> | ||
extends Runtype< | ||
Static<A> & | ||
Static<B> & | ||
Static<C> & | ||
Static<D> & | ||
Static<E> & | ||
Static<F> & | ||
Static<G> & | ||
Static<H> & | ||
Static<I> & | ||
Static<J> | ||
> { | ||
tag: 'intersect'; | ||
intersectees: [A, B, C, D, E, F, G, H, I, J]; | ||
} | ||
@@ -95,38 +142,91 @@ | ||
*/ | ||
export function Intersect<A extends Runtype>( | ||
export function Intersect<A extends Runtype>(A: A): Intersect1<A>; | ||
export function Intersect<A extends Runtype, B extends Runtype>(A: A, B: B): Intersect2<A, B>; | ||
export function Intersect<A extends Runtype, B extends Runtype, C extends Runtype>( | ||
A: A, | ||
): Intersect1<A> | ||
export function Intersect<A extends Runtype, B extends Runtype>( | ||
A: A, B: B, | ||
): Intersect2<A, B> | ||
export function Intersect<A extends Runtype, B extends Runtype, C extends Runtype>( | ||
A: A, B: B, C: C, | ||
): Intersect3<A, B, C> | ||
export function Intersect<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype>( | ||
A: A, B: B, C: C, D: D, | ||
): Intersect4<A, B, C, D> | ||
export function Intersect<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, | ||
): Intersect5<A, B, C, D, E> | ||
export function Intersect<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, | ||
): Intersect6<A, B, C, D, E, F> | ||
export function Intersect<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, G: G, | ||
): Intersect7<A, B, C, D, E, F, G> | ||
export function Intersect<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, | ||
): Intersect8<A, B, C, D, E, F, G, H> | ||
export function Intersect<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, I: I, | ||
): Intersect9<A, B, C, D, E, F, G, H, I> | ||
export function Intersect<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype, J extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, I: I, J: J, | ||
): Intersect10<A, B, C, D, E, F, G, H, I, J> | ||
B: B, | ||
C: C, | ||
): Intersect3<A, B, C>; | ||
export function Intersect< | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype | ||
>(A: A, B: B, C: C, D: D): Intersect4<A, B, C, D>; | ||
export function Intersect< | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype | ||
>(A: A, B: B, C: C, D: D, E: E): Intersect5<A, B, C, D, E>; | ||
export function Intersect< | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype | ||
>(A: A, B: B, C: C, D: D, E: E, F: F): Intersect6<A, B, C, D, E, F>; | ||
export function Intersect< | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype | ||
>(A: A, B: B, C: C, D: D, E: E, F: F, G: G): Intersect7<A, B, C, D, E, F, G>; | ||
export function Intersect< | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype, | ||
H extends Runtype | ||
>(A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H): Intersect8<A, B, C, D, E, F, G, H>; | ||
export function Intersect< | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype, | ||
H extends Runtype, | ||
I extends Runtype | ||
>(A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, I: I): Intersect9<A, B, C, D, E, F, G, H, I>; | ||
export function Intersect< | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype, | ||
H extends Runtype, | ||
I extends Runtype, | ||
J extends Runtype | ||
>( | ||
A: A, | ||
B: B, | ||
C: C, | ||
D: D, | ||
E: E, | ||
F: F, | ||
G: G, | ||
H: H, | ||
I: I, | ||
J: J, | ||
): Intersect10<A, B, C, D, E, F, G, H, I, J>; | ||
export function Intersect(...intersectees: Runtype[]): any { | ||
return create(x => { | ||
for (const { check } of intersectees) | ||
check(x) | ||
return x | ||
}, { tag: 'intersect', intersectees }) | ||
return create( | ||
x => { | ||
for (const { check } of intersectees) check(x); | ||
return x; | ||
}, | ||
{ tag: 'intersect', intersectees }, | ||
); | ||
} |
@@ -1,2 +0,2 @@ | ||
import { Runtype, create } from '../runtype' | ||
import { Runtype, create } from '../runtype'; | ||
@@ -8,19 +8,19 @@ /** | ||
const data: any = { | ||
get tag() { return (getWrapped() as any)['tag'] } | ||
} | ||
get tag() { | ||
return (getWrapped() as any)['tag']; | ||
}, | ||
}; | ||
let cached: A | ||
let cached: A; | ||
function getWrapped() { | ||
if (!cached) { | ||
cached = delayed() | ||
for (const k in cached) | ||
if (k !== 'tag') | ||
data[k] = cached[k] | ||
cached = delayed(); | ||
for (const k in cached) if (k !== 'tag') data[k] = cached[k]; | ||
} | ||
return cached | ||
return cached; | ||
} | ||
return create<A>(x => { | ||
return getWrapped().check(x) | ||
}, data) | ||
return getWrapped().check(x); | ||
}, data); | ||
} |
@@ -1,2 +0,2 @@ | ||
import { Runtype, create, validationError } from '../runtype' | ||
import { Runtype, create, validationError } from '../runtype'; | ||
@@ -6,7 +6,7 @@ /** | ||
*/ | ||
export type LiteralBase = undefined | null | boolean | number | string | ||
export type LiteralBase = undefined | null | boolean | number | string; | ||
export interface Literal<A extends LiteralBase> extends Runtype<A> { | ||
tag: 'literal' | ||
value: A | ||
tag: 'literal'; | ||
value: A; | ||
} | ||
@@ -18,7 +18,9 @@ | ||
export function Literal<A extends LiteralBase>(value: A): Literal<A> { | ||
return create<Literal<A>>(x => { | ||
if (x !== value) | ||
throw validationError(`Expected literal '${value}' but was '${x}'`) | ||
return x as A | ||
}, { tag: 'literal', value }) | ||
return create<Literal<A>>( | ||
x => { | ||
if (x !== value) throw validationError(`Expected literal '${value}' but was '${x}'`); | ||
return x as A; | ||
}, | ||
{ tag: 'literal', value }, | ||
); | ||
} | ||
@@ -29,3 +31,3 @@ | ||
*/ | ||
export const Undefined = Literal(undefined) | ||
export const Undefined = Literal(undefined); | ||
@@ -35,2 +37,2 @@ /** | ||
*/ | ||
export const Null = Literal(null) | ||
export const Null = Literal(null); |
@@ -1,4 +0,6 @@ | ||
import { Runtype, create, validationError } from '../runtype' | ||
import { Runtype, create, validationError } from '../runtype'; | ||
export interface Never extends Runtype<never> { tag: 'never' } | ||
export interface Never extends Runtype<never> { | ||
tag: 'never'; | ||
} | ||
@@ -8,4 +10,7 @@ /** | ||
*/ | ||
export const Never = create<Never>(() => { | ||
throw validationError('Expected nothing but got something') | ||
}, { tag: 'never' }) | ||
export const Never = create<Never>( | ||
() => { | ||
throw validationError('Expected nothing but got something'); | ||
}, | ||
{ tag: 'never' }, | ||
); |
@@ -1,4 +0,6 @@ | ||
import { Runtype, create, validationError } from '../runtype' | ||
import { Runtype, create, validationError } from '../runtype'; | ||
export interface Number extends Runtype<number> { tag: 'number' } | ||
export interface Number extends Runtype<number> { | ||
tag: 'number'; | ||
} | ||
@@ -8,6 +10,8 @@ /** | ||
*/ | ||
export const Number = create<Number>(x => { | ||
if (typeof x !== 'number') | ||
throw validationError(`Expected number but was ${typeof x}`) | ||
return x | ||
}, { tag: 'number' }) | ||
export const Number = create<Number>( | ||
x => { | ||
if (typeof x !== 'number') throw validationError(`Expected number but was ${typeof x}`); | ||
return x; | ||
}, | ||
{ tag: 'number' }, | ||
); |
@@ -1,9 +0,10 @@ | ||
import { Runtype, Static, create, validationError } from '../runtype' | ||
import { Union } from '../index' | ||
import { Undefined } from './literal' | ||
import { hasKey } from '../util' | ||
import { Runtype, Static, create, validationError } from '../runtype'; | ||
import { Union } from '../index'; | ||
import { Undefined } from './literal'; | ||
import { hasKey } from '../util'; | ||
export interface Part<O extends {[_ in string]: Runtype }> extends Runtype<{[K in keyof O]?: Static<O[K]> }> { | ||
tag: 'partial' | ||
fields: O | ||
export interface Part<O extends { [_ in string]: Runtype }> | ||
extends Runtype<{ [K in keyof O]?: Static<O[K]> }> { | ||
tag: 'partial'; | ||
fields: O; | ||
} | ||
@@ -15,20 +16,23 @@ | ||
export function Part<O extends { [_: string]: Runtype }>(fields: O) { | ||
return create<Part<O>>(x => { | ||
if (x === null || x === undefined) | ||
throw validationError(`Expected a defined non-null value but was ${typeof x}`) | ||
return create<Part<O>>( | ||
x => { | ||
if (x === null || x === undefined) | ||
throw validationError(`Expected a defined non-null value but was ${typeof x}`); | ||
// tslint:disable-next-line:forin | ||
for (const key in fields) | ||
if (hasKey(key, x)) { | ||
try { | ||
Union(fields[key], Undefined).check(x[key]) | ||
} catch ({ message }) { | ||
throw validationError(`In key ${key}: ${message}`) | ||
// tslint:disable-next-line:forin | ||
for (const key in fields) | ||
if (hasKey(key, x)) { | ||
try { | ||
Union(fields[key], Undefined).check(x[key]); | ||
} catch ({ message }) { | ||
throw validationError(`In key ${key}: ${message}`); | ||
} | ||
} | ||
} | ||
return x as Partial<O> | ||
}, { tag: 'partial', fields }) | ||
return x as Partial<O>; | ||
}, | ||
{ tag: 'partial', fields }, | ||
); | ||
} | ||
export { Part as Partial } | ||
export { Part as Partial }; |
@@ -1,7 +0,8 @@ | ||
import { Runtype, Static, create, validationError } from '../runtype' | ||
import { hasKey } from '../util' | ||
import { Runtype, Static, create, validationError } from '../runtype'; | ||
import { hasKey } from '../util'; | ||
export interface Record<O extends { [_ in string]: Runtype }> extends Runtype<{[K in keyof O]: Static<O[K]> }> { | ||
tag: 'record' | ||
fields: O | ||
export interface Record<O extends { [_ in string]: Runtype }> | ||
extends Runtype<{ [K in keyof O]: Static<O[K]> }> { | ||
tag: 'record'; | ||
fields: O; | ||
} | ||
@@ -13,20 +14,22 @@ | ||
export function Record<O extends { [_: string]: Runtype }>(fields: O) { | ||
return create<Record<O>>(x => { | ||
if (x === null || x === undefined) | ||
throw validationError(`Expected a defined non-null value but was ${typeof x}`) | ||
return create<Record<O>>( | ||
x => { | ||
if (x === null || x === undefined) | ||
throw validationError(`Expected a defined non-null value but was ${typeof x}`); | ||
// tslint:disable-next-line:forin | ||
for (const key in fields) { | ||
if (hasKey(key, x)) { | ||
try { | ||
fields[key].check(x[key]) | ||
} catch ({ message }) { | ||
throw validationError(`In key ${key}: ${message}`) | ||
} | ||
} else | ||
throw validationError(`Missing property ${key}`) | ||
} | ||
// tslint:disable-next-line:forin | ||
for (const key in fields) { | ||
if (hasKey(key, x)) { | ||
try { | ||
fields[key].check(x[key]); | ||
} catch ({ message }) { | ||
throw validationError(`In key ${key}: ${message}`); | ||
} | ||
} else throw validationError(`Missing property ${key}`); | ||
} | ||
return x as O | ||
}, { tag: 'record', fields }) | ||
return x as O; | ||
}, | ||
{ tag: 'record', fields }, | ||
); | ||
} |
@@ -1,4 +0,6 @@ | ||
import { Runtype, create, validationError } from '../runtype' | ||
import { Runtype, create, validationError } from '../runtype'; | ||
export interface String extends Runtype<string> { tag: 'string' } | ||
export interface String extends Runtype<string> { | ||
tag: 'string'; | ||
} | ||
@@ -8,6 +10,8 @@ /** | ||
*/ | ||
export const String = create<String>(x => { | ||
if (typeof x !== 'string') | ||
throw validationError(`Expected string but was ${typeof x}`) | ||
return x | ||
}, { tag: 'string' }) | ||
export const String = create<String>( | ||
x => { | ||
if (typeof x !== 'string') throw validationError(`Expected string but was ${typeof x}`); | ||
return x; | ||
}, | ||
{ tag: 'string' }, | ||
); |
@@ -1,91 +0,137 @@ | ||
import { Runtype, Static, create, validationError } from '../runtype' | ||
import { Always } from './always' | ||
import { Array as Arr } from './array' | ||
import { Runtype, Static, create, validationError } from '../runtype'; | ||
import { Always } from './always'; | ||
import { Array as Arr } from './array'; | ||
export interface Tuple1< | ||
A extends Runtype, | ||
> extends Runtype<[Static<A>]> { | ||
tag: 'tuple' | ||
components: [A] | ||
export interface Tuple1<A extends Runtype> extends Runtype<[Static<A>]> { | ||
tag: 'tuple'; | ||
components: [A]; | ||
} | ||
export interface Tuple2< | ||
A extends Runtype, B extends Runtype, | ||
> extends Runtype<[ | ||
Static<A>, Static<B> | ||
]> { | ||
tag: 'tuple' | ||
components: [A, B] | ||
export interface Tuple2<A extends Runtype, B extends Runtype> | ||
extends Runtype<[Static<A>, Static<B>]> { | ||
tag: 'tuple'; | ||
components: [A, B]; | ||
} | ||
export interface Tuple3< | ||
A extends Runtype, B extends Runtype, C extends Runtype, | ||
> extends Runtype<[ | ||
Static<A>, Static<B>, Static<C> | ||
]> { | ||
tag: 'tuple' | ||
components: [A, B, C] | ||
export interface Tuple3<A extends Runtype, B extends Runtype, C extends Runtype> | ||
extends Runtype<[Static<A>, Static<B>, Static<C>]> { | ||
tag: 'tuple'; | ||
components: [A, B, C]; | ||
} | ||
export interface Tuple4< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, | ||
> extends Runtype<[ | ||
Static<A>, Static<B>, Static<C>, Static<D> | ||
]> { | ||
tag: 'tuple' | ||
components: [A, B, C, D] | ||
export interface Tuple4<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype> | ||
extends Runtype<[Static<A>, Static<B>, Static<C>, Static<D>]> { | ||
tag: 'tuple'; | ||
components: [A, B, C, D]; | ||
} | ||
export interface Tuple5< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, | ||
> extends Runtype<[ | ||
Static<A>, Static<B>, Static<C>, Static<D>, Static<E> | ||
]> { | ||
tag: 'tuple' | ||
components: [A, B, C, D, E] | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype | ||
> extends Runtype<[Static<A>, Static<B>, Static<C>, Static<D>, Static<E>]> { | ||
tag: 'tuple'; | ||
components: [A, B, C, D, E]; | ||
} | ||
export interface Tuple6< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, | ||
> extends Runtype<[ | ||
Static<A>, Static<B>, Static<C>, Static<D>, Static<E>, Static<F> | ||
]> { | ||
tag: 'tuple' | ||
components: [A, B, C, D, E, F] | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype | ||
> extends Runtype<[Static<A>, Static<B>, Static<C>, Static<D>, Static<E>, Static<F>]> { | ||
tag: 'tuple'; | ||
components: [A, B, C, D, E, F]; | ||
} | ||
export interface Tuple7< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, | ||
> extends Runtype<[ | ||
Static<A>, Static<B>, Static<C>, Static<D>, Static<E>, Static<F>, Static<G> | ||
]> { | ||
tag: 'tuple' | ||
components: [A, B, C, D, E, F, G] | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype | ||
> extends Runtype<[Static<A>, Static<B>, Static<C>, Static<D>, Static<E>, Static<F>, Static<G>]> { | ||
tag: 'tuple'; | ||
components: [A, B, C, D, E, F, G]; | ||
} | ||
export interface Tuple8< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, | ||
> extends Runtype<[ | ||
Static<A>, Static<B>, Static<C>, Static<D>, Static<E>, Static<F>, Static<G>, Static<H> | ||
]> { | ||
tag: 'tuple' | ||
components: [A, B, C, D, E, F, G, H] | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype, | ||
H extends Runtype | ||
> | ||
extends Runtype< | ||
[Static<A>, Static<B>, Static<C>, Static<D>, Static<E>, Static<F>, Static<G>, Static<H>] | ||
> { | ||
tag: 'tuple'; | ||
components: [A, B, C, D, E, F, G, H]; | ||
} | ||
export interface Tuple9< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype, | ||
> extends Runtype<[ | ||
Static<A>, Static<B>, Static<C>, Static<D>, Static<E>, Static<F>, Static<G>, Static<H>, Static<I> | ||
]> { | ||
tag: 'tuple' | ||
components: [A, B, C, D, E, F, G, H, I] | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype, | ||
H extends Runtype, | ||
I extends Runtype | ||
> | ||
extends Runtype< | ||
[ | ||
Static<A>, | ||
Static<B>, | ||
Static<C>, | ||
Static<D>, | ||
Static<E>, | ||
Static<F>, | ||
Static<G>, | ||
Static<H>, | ||
Static<I> | ||
] | ||
> { | ||
tag: 'tuple'; | ||
components: [A, B, C, D, E, F, G, H, I]; | ||
} | ||
export interface Tuple10< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype, J extends Runtype, | ||
> extends Runtype<[ | ||
Static<A>, Static<B>, Static<C>, Static<D>, Static<E>, Static<F>, Static<G>, Static<H>, Static<I>, Static<J> | ||
]> { | ||
tag: 'tuple' | ||
components: [A, B, C, D, E, F, G, H, I, J] | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype, | ||
H extends Runtype, | ||
I extends Runtype, | ||
J extends Runtype | ||
> | ||
extends Runtype< | ||
[ | ||
Static<A>, | ||
Static<B>, | ||
Static<C>, | ||
Static<D>, | ||
Static<E>, | ||
Static<F>, | ||
Static<G>, | ||
Static<H>, | ||
Static<I>, | ||
Static<J> | ||
] | ||
> { | ||
tag: 'tuple'; | ||
components: [A, B, C, D, E, F, G, H, I, J]; | ||
} | ||
@@ -96,41 +142,94 @@ | ||
*/ | ||
export function Tuple<A extends Runtype>( | ||
export function Tuple<A extends Runtype>(A: A): Tuple1<A>; | ||
export function Tuple<A extends Runtype, B extends Runtype>(A: A, B: B): Tuple2<A, B>; | ||
export function Tuple<A extends Runtype, B extends Runtype, C extends Runtype>( | ||
A: A, | ||
): Tuple1<A> | ||
export function Tuple<A extends Runtype, B extends Runtype>( | ||
A: A, B: B, | ||
): Tuple2<A, B> | ||
export function Tuple<A extends Runtype, B extends Runtype, C extends Runtype>( | ||
A: A, B: B, C: C, | ||
): Tuple3<A, B, C> | ||
B: B, | ||
C: C, | ||
): Tuple3<A, B, C>; | ||
export function Tuple<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype>( | ||
A: A, B: B, C: C, D: D, | ||
): Tuple4<A, B, C, D> | ||
export function Tuple<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, | ||
): Tuple5<A, B, C, D, E> | ||
export function Tuple<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, | ||
): Tuple6<A, B, C, D, E, F> | ||
export function Tuple<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, G: G, | ||
): Tuple7<A, B, C, D, E, F, G> | ||
export function Tuple<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, | ||
): Tuple8<A, B, C, D, E, F, G, H> | ||
export function Tuple<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, I: I, | ||
): Tuple9<A, B, C, D, E, F, G, H, I> | ||
export function Tuple<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype, J extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, I: I, J: J, | ||
): Tuple10<A, B, C, D, E, F, G, H, I, J> | ||
A: A, | ||
B: B, | ||
C: C, | ||
D: D, | ||
): Tuple4<A, B, C, D>; | ||
export function Tuple< | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype | ||
>(A: A, B: B, C: C, D: D, E: E): Tuple5<A, B, C, D, E>; | ||
export function Tuple< | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype | ||
>(A: A, B: B, C: C, D: D, E: E, F: F): Tuple6<A, B, C, D, E, F>; | ||
export function Tuple< | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype | ||
>(A: A, B: B, C: C, D: D, E: E, F: F, G: G): Tuple7<A, B, C, D, E, F, G>; | ||
export function Tuple< | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype, | ||
H extends Runtype | ||
>(A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H): Tuple8<A, B, C, D, E, F, G, H>; | ||
export function Tuple< | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype, | ||
H extends Runtype, | ||
I extends Runtype | ||
>(A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, I: I): Tuple9<A, B, C, D, E, F, G, H, I>; | ||
export function Tuple< | ||
A extends Runtype, | ||
B extends Runtype, | ||
C extends Runtype, | ||
D extends Runtype, | ||
E extends Runtype, | ||
F extends Runtype, | ||
G extends Runtype, | ||
H extends Runtype, | ||
I extends Runtype, | ||
J extends Runtype | ||
>( | ||
A: A, | ||
B: B, | ||
C: C, | ||
D: D, | ||
E: E, | ||
F: F, | ||
G: G, | ||
H: H, | ||
I: I, | ||
J: J, | ||
): Tuple10<A, B, C, D, E, F, G, H, I, J>; | ||
export function Tuple(...components: Runtype[]): any { | ||
return create(x => { | ||
const xs = Arr(Always).check(x) | ||
if (xs.length < components.length) | ||
throw validationError(`Expected array of ${components.length} but was ${xs.length}`) | ||
for (let i = 0; i < components.length; i++) | ||
components[i].check(xs[i]) | ||
return x | ||
}, { tag: 'tuple', components }) | ||
return create( | ||
x => { | ||
const xs = Arr(Always).check(x); | ||
if (xs.length < components.length) | ||
throw validationError(`Expected array of ${components.length} but was ${xs.length}`); | ||
for (let i = 0; i < components.length; i++) components[i].check(xs[i]); | ||
return x; | ||
}, | ||
{ tag: 'tuple', components }, | ||
); | ||
} |
@@ -1,91 +0,134 @@ | ||
import { Runtype, Static, create } from '../runtype' | ||
import { Runtype as Rt, Static, create } from '../runtype'; | ||
export interface Union1< | ||
A extends Runtype, | ||
> extends Runtype< | ||
Static<A> | ||
> { | ||
tag: 'union' | ||
alternatives: [A] | ||
export interface Union1<A extends Rt> extends Rt<Static1<A>> { | ||
tag: 'union'; | ||
alternatives: [A]; | ||
match: Match1<A>; | ||
} | ||
export interface Union2< | ||
A extends Runtype, B extends Runtype, | ||
> extends Runtype< | ||
Static<A> | Static<B> | ||
> { | ||
tag: 'union' | ||
alternatives: [A, B] | ||
export interface Union2<A extends Rt, B extends Rt> extends Rt<Static2<A, B>> { | ||
tag: 'union'; | ||
alternatives: [A, B]; | ||
match: Match2<A, B>; | ||
} | ||
export interface Union3< | ||
A extends Runtype, B extends Runtype, C extends Runtype, | ||
> extends Runtype< | ||
Static<A> | Static<B> | Static<C> | ||
> { | ||
tag: 'union' | ||
alternatives: [A, B, C] | ||
export interface Union3<A extends Rt, B extends Rt, C extends Rt> extends Rt<Static3<A, B, C>> { | ||
tag: 'union'; | ||
alternatives: [A, B, C]; | ||
match: Match3<A, B, C>; | ||
} | ||
export interface Union4< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, | ||
> extends Runtype< | ||
Static<A> | Static<B> | Static<C> | Static<D> | ||
> { | ||
tag: 'union' | ||
alternatives: [A, B, C, D] | ||
export interface Union4<A extends Rt, B extends Rt, C extends Rt, D extends Rt> | ||
extends Rt<Static<A> | Static<B> | Static<C> | Static<D>> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D]; | ||
match: Match4<A, B, C, D>; | ||
} | ||
export interface Union5< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, | ||
> extends Runtype< | ||
Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | ||
> { | ||
tag: 'union' | ||
alternatives: [A, B, C, D, E] | ||
export interface Union5<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt> | ||
extends Rt<Static<A> | Static<B> | Static<C> | Static<D> | Static<E>> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D, E]; | ||
match: Match5<A, B, C, D, E>; | ||
} | ||
export interface Union6< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, | ||
> extends Runtype< | ||
Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | ||
> { | ||
tag: 'union' | ||
alternatives: [A, B, C, D, E, F] | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt | ||
> extends Rt<Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F>> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D, E, F]; | ||
match: Match6<A, B, C, D, E, F>; | ||
} | ||
export interface Union7< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, | ||
> extends Runtype< | ||
Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | ||
> { | ||
tag: 'union' | ||
alternatives: [A, B, C, D, E, F, G] | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt | ||
> extends Rt<Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G>> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D, E, F, G]; | ||
match: Match7<A, B, C, D, E, F, G>; | ||
} | ||
export interface Union8< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, | ||
> extends Runtype< | ||
Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H> | ||
> { | ||
tag: 'union' | ||
alternatives: [A, B, C, D, E, F, G, H] | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt, | ||
H extends Rt | ||
> | ||
extends Rt< | ||
Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H> | ||
> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D, E, F, G, H]; | ||
match: Match8<A, B, C, D, E, F, G, H>; | ||
} | ||
export interface Union9< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype, | ||
> extends Runtype< | ||
Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H> | Static<I> | ||
> { | ||
tag: 'union' | ||
alternatives: [A, B, C, D, E, F, G, H, I] | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt, | ||
H extends Rt, | ||
I extends Rt | ||
> | ||
extends Rt< | ||
| Static<A> | ||
| Static<B> | ||
| Static<C> | ||
| Static<D> | ||
| Static<E> | ||
| Static<F> | ||
| Static<G> | ||
| Static<H> | ||
| Static<I> | ||
> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D, E, F, G, H, I]; | ||
match: Match9<A, B, C, D, E, F, G, H, I>; | ||
} | ||
export interface Union10< | ||
A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype, J extends Runtype, | ||
> extends Runtype< | ||
Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H> | Static<I> | Static<J> | ||
> { | ||
tag: 'union' | ||
alternatives: [A, B, C, D, E, F, G, H, I, J] | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt, | ||
H extends Rt, | ||
I extends Rt, | ||
J extends Rt | ||
> | ||
extends Rt< | ||
| Static<A> | ||
| Static<B> | ||
| Static<C> | ||
| Static<D> | ||
| Static<E> | ||
| Static<F> | ||
| Static<G> | ||
| Static<H> | ||
| Static<I> | ||
| Static<J> | ||
> { | ||
tag: 'union'; | ||
alternatives: [A, B, C, D, E, F, G, H, I, J]; | ||
match: Match10<A, B, C, D, E, F, G, H, I, J>; | ||
} | ||
@@ -96,39 +139,299 @@ | ||
*/ | ||
export function Union<A extends Runtype>( | ||
export function Union<A extends Rt>(A: A): Union1<A>; | ||
export function Union<A extends Rt, B extends Rt>(A: A, B: B): Union2<A, B>; | ||
export function Union<A extends Rt, B extends Rt, C extends Rt>(A: A, B: B, C: C): Union3<A, B, C>; | ||
export function Union<A extends Rt, B extends Rt, C extends Rt, D extends Rt>( | ||
A: A, | ||
): Union1<A> | ||
export function Union<A extends Runtype, B extends Runtype>( | ||
A: A, B: B, | ||
): Union2<A, B> | ||
export function Union<A extends Runtype, B extends Runtype, C extends Runtype>( | ||
A: A, B: B, C: C, | ||
): Union3<A, B, C> | ||
export function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype>( | ||
A: A, B: B, C: C, D: D, | ||
): Union4<A, B, C, D> | ||
export function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, | ||
): Union5<A, B, C, D, E> | ||
export function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, | ||
): Union6<A, B, C, D, E, F> | ||
export function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, G: G, | ||
): Union7<A, B, C, D, E, F, G> | ||
export function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, | ||
): Union8<A, B, C, D, E, F, G, H> | ||
export function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, I: I, | ||
): Union9<A, B, C, D, E, F, G, H, I> | ||
export function Union<A extends Runtype, B extends Runtype, C extends Runtype, D extends Runtype, E extends Runtype, F extends Runtype, G extends Runtype, H extends Runtype, I extends Runtype, J extends Runtype>( | ||
A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, I: I, J: J, | ||
): Union10<A, B, C, D, E, F, G, H, I, J> | ||
export function Union(...alternatives: Runtype[]): any { | ||
return create(x => { | ||
for (const { guard } of alternatives) | ||
if (guard(x)) | ||
return x | ||
throw new Error('No alternatives were matched') | ||
}, { tag: 'union', alternatives }) | ||
B: B, | ||
C: C, | ||
D: D, | ||
): Union4<A, B, C, D>; | ||
export function Union<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt>( | ||
A: A, | ||
B: B, | ||
C: C, | ||
D: D, | ||
E: E, | ||
): Union5<A, B, C, D, E>; | ||
export function Union< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt | ||
>(A: A, B: B, C: C, D: D, E: E, F: F): Union6<A, B, C, D, E, F>; | ||
export function Union< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt | ||
>(A: A, B: B, C: C, D: D, E: E, F: F, G: G): Union7<A, B, C, D, E, F, G>; | ||
export function Union< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt, | ||
H extends Rt | ||
>(A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H): Union8<A, B, C, D, E, F, G, H>; | ||
export function Union< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt, | ||
H extends Rt, | ||
I extends Rt | ||
>(A: A, B: B, C: C, D: D, E: E, F: F, G: G, H: H, I: I): Union9<A, B, C, D, E, F, G, H, I>; | ||
export function Union< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt, | ||
H extends Rt, | ||
I extends Rt, | ||
J extends Rt | ||
>( | ||
A: A, | ||
B: B, | ||
C: C, | ||
D: D, | ||
E: E, | ||
F: F, | ||
G: G, | ||
H: H, | ||
I: I, | ||
J: J, | ||
): Union10<A, B, C, D, E, F, G, H, I, J>; | ||
export function Union(...alternatives: Rt[]): any { | ||
const match = (cases: any[]) => (x: any) => { | ||
for (let i = 0; i < alternatives.length; i++) { | ||
if (alternatives[i].guard(x)) { | ||
return cases[i](x); | ||
} | ||
} | ||
}; | ||
return create( | ||
x => { | ||
for (const { guard } of alternatives) if (guard(x)) return x; | ||
throw new Error('No alternatives were matched'); | ||
}, | ||
{ tag: 'union', alternatives, match }, | ||
); | ||
} | ||
export interface Match1<A extends Rt> { | ||
<Z>(cases: [Case<A, Z>]): (x: Static1<A>) => Z; | ||
} | ||
export interface Match2<A extends Rt, B extends Rt> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>]): (x: Static2<A, B>) => Z; | ||
} | ||
export interface Match3<A extends Rt, B extends Rt, C extends Rt> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>, Case<C, Z>]): (x: Static3<A, B, C>) => Z; | ||
} | ||
export interface Match4<A extends Rt, B extends Rt, C extends Rt, D extends Rt> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>, Case<C, Z>, Case<D, Z>]): (x: Static4<A, B, C, D>) => Z; | ||
} | ||
export interface Match5<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>, Case<C, Z>, Case<D, Z>, Case<E, Z>]): ( | ||
x: Static5<A, B, C, D, E>, | ||
) => Z; | ||
} | ||
export interface Match6< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt | ||
> { | ||
<Z>(cases: [Case<A, Z>, Case<B, Z>, Case<C, Z>, Case<D, Z>, Case<E, Z>, Case<F, Z>]): ( | ||
x: Static6<A, B, C, D, E, F>, | ||
) => Z; | ||
} | ||
export interface Match7< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt | ||
> { | ||
<Z>( | ||
cases: [Case<A, Z>, Case<B, Z>, Case<C, Z>, Case<D, Z>, Case<E, Z>, Case<F, Z>, Case<G, Z>], | ||
): (x: Static7<A, B, C, D, E, F, G>) => Z; | ||
} | ||
export interface Match8< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt, | ||
H extends Rt | ||
> { | ||
<Z>( | ||
cases: [ | ||
Case<A, Z>, | ||
Case<B, Z>, | ||
Case<C, Z>, | ||
Case<D, Z>, | ||
Case<E, Z>, | ||
Case<F, Z>, | ||
Case<G, Z>, | ||
Case<H, Z> | ||
], | ||
): (x: Static8<A, B, C, D, E, F, G, H>) => Z; | ||
} | ||
export interface Match9< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt, | ||
H extends Rt, | ||
I extends Rt | ||
> { | ||
<Z>( | ||
cases: [ | ||
Case<A, Z>, | ||
Case<B, Z>, | ||
Case<C, Z>, | ||
Case<D, Z>, | ||
Case<E, Z>, | ||
Case<F, Z>, | ||
Case<G, Z>, | ||
Case<H, Z>, | ||
Case<I, Z> | ||
], | ||
): (x: Static9<A, B, C, D, E, F, G, H, I>) => Z; | ||
} | ||
export interface Match10< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt, | ||
H extends Rt, | ||
I extends Rt, | ||
J extends Rt | ||
> { | ||
<Z>( | ||
cases: [ | ||
Case<A, Z>, | ||
Case<B, Z>, | ||
Case<C, Z>, | ||
Case<D, Z>, | ||
Case<E, Z>, | ||
Case<F, Z>, | ||
Case<G, Z>, | ||
Case<H, Z>, | ||
Case<I, Z>, | ||
Case<J, Z> | ||
], | ||
): (x: Static10<A, B, C, D, E, F, G, H, I, J>) => Z; | ||
} | ||
export type Case<T extends Rt, Result> = (v: Static<T>) => Result; | ||
export type Static1<A extends Rt> = Static<A>; | ||
export type Static2<A extends Rt, B extends Rt> = Static<A> | Static<B>; | ||
export type Static3<A extends Rt, B extends Rt, C extends Rt> = Static<A> | Static<B> | Static<C>; | ||
export type Static4<A extends Rt, B extends Rt, C extends Rt, D extends Rt> = | ||
| Static<A> | ||
| Static<B> | ||
| Static<C> | ||
| Static<D>; | ||
export type Static5<A extends Rt, B extends Rt, C extends Rt, D extends Rt, E extends Rt> = | ||
| Static<A> | ||
| Static<B> | ||
| Static<C> | ||
| Static<D> | ||
| Static<E>; | ||
export type Static6< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt | ||
> = Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F>; | ||
export type Static7< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt | ||
> = Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G>; | ||
export type Static8< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt, | ||
H extends Rt | ||
> = Static<A> | Static<B> | Static<C> | Static<D> | Static<E> | Static<F> | Static<G> | Static<H>; | ||
export type Static9< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt, | ||
H extends Rt, | ||
I extends Rt | ||
> = | ||
| Static<A> | ||
| Static<B> | ||
| Static<C> | ||
| Static<D> | ||
| Static<E> | ||
| Static<F> | ||
| Static<G> | ||
| Static<H> | ||
| Static<I>; | ||
export type Static10< | ||
A extends Rt, | ||
B extends Rt, | ||
C extends Rt, | ||
D extends Rt, | ||
E extends Rt, | ||
F extends Rt, | ||
G extends Rt, | ||
H extends Rt, | ||
I extends Rt, | ||
J extends Rt | ||
> = | ||
| Static<A> | ||
| Static<B> | ||
| Static<C> | ||
| Static<D> | ||
| Static<E> | ||
| Static<F> | ||
| Static<G> | ||
| Static<H> | ||
| Static<I> | ||
| Static<J>; |
@@ -1,4 +0,6 @@ | ||
import { Runtype, create, validationError } from '../runtype' | ||
import { Runtype, create, validationError } from '../runtype'; | ||
export interface Void extends Runtype<void> { tag: 'void' } | ||
export interface Void extends Runtype<void> { | ||
tag: 'void'; | ||
} | ||
@@ -8,6 +10,8 @@ /** | ||
*/ | ||
export const Void = create<Void>(x => { | ||
if (x !== undefined && x !== null) | ||
throw validationError(`Expected null but was ${typeof x}`) | ||
return x | ||
}, { tag: 'void' }) | ||
export const Void = create<Void>( | ||
x => { | ||
if (x !== undefined && x !== null) throw validationError(`Expected null but was ${typeof x}`); | ||
return x; | ||
}, | ||
{ tag: 'void' }, | ||
); |
// Type guard to determine if an object has a given key | ||
// If this feature gets implemented, we can use `in` instead: https://github.com/Microsoft/TypeScript/issues/10485 | ||
export function hasKey<K extends string>(k: K, o: {}): o is {[_ in K]: {} } { | ||
return typeof o === 'object' && k in o | ||
export function hasKey<K extends string>(k: K, o: {}): o is { [_ in K]: {} } { | ||
return typeof o === 'object' && k in o; | ||
} |
{ | ||
"compilerOptions": { | ||
"module": "commonjs", | ||
"target": "es5", | ||
"lib": ["es2015"], | ||
"strict": true, | ||
"noUnusedLocals": true, | ||
"noUnusedParameters": true, | ||
"declaration": true, | ||
"sourceMap": false, | ||
"outDir": "lib", | ||
"forceConsistentCasingInFileNames": true | ||
}, | ||
"files": [ | ||
"src/index.ts" | ||
] | ||
"compilerOptions": { | ||
"module": "commonjs", | ||
"target": "es5", | ||
"lib": ["es2015"], | ||
"strict": true, | ||
"noUnusedLocals": true, | ||
"noUnusedParameters": true, | ||
"declaration": true, | ||
"sourceMap": false, | ||
"outDir": "lib", | ||
"forceConsistentCasingInFileNames": true | ||
}, | ||
"files": ["src/index.ts"] | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
114664
91
3176
1
6