diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index d4cc35d4e..f2ca4fe08 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -678,6 +678,7 @@ This document generated by [dt-contributors-generator](https://github.com/vvakam * [:link:](swiz/swiz.d.ts) [swiz](https://github.com/racker/node-swiz) by [Jeff Goddard](https://github.com/jedigo) * [:link:](tape/tape.d.ts) [tape](https://github.com/substack/tape) by [Bart van der Schoor](https://github.com/Bartvds) * [:link:](tar/tar.d.ts) [tar](https://github.com/npm/node-tar) by [Maxime LUCE](https://github.com/SomaticIT) +* [:link:](tcomb/tcomb.d.ts) [tcomb](https://github.com/npm/tcomb) by [Jed Mao](https://github.com/jedmao) * [:link:](tedious/tedious.d.ts) [tedious](https://pekim.github.io/tedious) by [Rogier Schouten](https://github.com/rogierschouten) * [:link:](tedious-connection-pool/tedious-connection-pool.d.ts) [tedious-connection-pool](https://github.com/pekim/tedious-connection-pool) by [Cyprien Autexier](https://github.com/sandorfr) * [:link:](teechart/teechart.d.ts) [TeeChart](http://www.steema.com) by [Steema Software](https://steema.com) diff --git a/tcomb/tcomb-tests.ts b/tcomb/tcomb-tests.ts new file mode 100644 index 000000000..aeecdcb31 --- /dev/null +++ b/tcomb/tcomb-tests.ts @@ -0,0 +1,288 @@ +// ReSharper disable InconsistentNaming +// ReSharper disable WrongExpressionStatement + +import t = require("tcomb"); + +var Str = t.Str; +var Num = t.Num; +var Bool = t.Bool; +var Arr = t.Arr; +var Obj = t.Obj; +var Func = t.Func; +var Err = t.Err; +var Re = t.Re; +var Dat = t.Dat; +var Nil = t.Nil; +var Any = t.Any; +var Type = t.Type; + +var struct = t.struct; +var tuple = t.tuple; +var list = t.list; +var dict = t.dict; +var union = t.union; +var maybe = t.maybe; +var func = t.func; +var subtype = t.subtype; + +Str.is("a string"); // => true +Str.is(1); // => false + +Num.is("a string"); // => true +Num.is(1); // => false + +Bool.is("a string"); // => true +Bool.is(1); // => false + +Arr.is("a string"); // => true +Arr.is(1); // => false + +Obj.is("a string"); // => true +Obj.is(1); // => false + +Func.is("a string"); // => true +Func.is(1); // => false + +Err.is("a string"); // => true +Err.is(1); // => false + +Re.is("a string"); // => true +Re.is(1); // => false + +Dat.is("a string"); // => true +Dat.is(1); // => false + +Nil.is("a string"); // => true +Nil.is(1); // => false + +Any.is("a string"); // => true +Any.is(1); // => false + +Type.is("a string"); // => true +Type.is(1); // => false + +var assert = t.assert; + +assert(t.Str.is("a string")); // => ok +assert(t.Str.is(1)); // => fail! + +var x = -2; +var min = 0; +// throws "-2 should be greater then 0" +assert(x > min, "%s should be greater then %s", x, min); + +Str("a string"); // => ok + +class Point1 { + x: number; + y: number; + constructor(x: number, y: number) { + this.x = Num(x); + this.y = Num(y); + } +} + +var Foo = t.irreducible("Foo", x => { + return t.Bool(x.hasOwnProperty("bar")); +}); + +Foo.is({ bar: "baz" }); // => true + +// defines a type representing positive numbers +var Positive = t.subtype(t.Num, n => { + return n >= 0; +}, "Positive"); + +Positive.is(1); // => true +Positive.is(-1); // => false + +var Country = t.enums({ + IT: "Italy", + US: "United States" +}, "Country"); + +Country.is("IT"); // => true +Country.is("FR"); // => false + +// values will mirror the keys +Country = t.enums.of("IT US", "Country"); + +// same as + +Country = t.enums(["IT", "US"], "Country"); + +// same as + +Country = t.enums({ + IT: "IT", + US: "US" +}, "Country"); + +var Point = t.struct({ + x: Num, + y: Num +}, "Point"); + +// constructor usage, `p` is immutable, new is optional +var p2 = new Point({ x: 1, y: 2 }); + +Point.is(p2); // => true + +// now p is mutable +new Point({ x: 1, y: 2 }, true); + +Point.extend({ z: Num }, "Point3D"); + +// multiple inheritance +var A = struct({}); +var B = struct({}); +var MixinC = {}; +var MixinD = {}; +A.extend([B, MixinC, MixinD]); + +var Rectangle = struct({ + width: Num, + height: Num +}); + +Rectangle.prototype.getArea = function() { + return this.width * this.height; +}; + +var Cube = Rectangle.extend({ + thickness: Num +}); + +// typeof Cube.prototype.getArea === 'function' +Cube.prototype.getVolume = function() { + return this.getArea() * this.thickness; +}; + +var Area = tuple([Num, Num]); + +// constructor usage, `area` is immutable +Area([1, 2]); + +var Path = list(Point); + +// costructor usage, `path` is immutable +Path([ + { x: 0, y: 0 }, // tcomb hydrates automatically using the `Point` constructor + { x: 1, y: 1 } +]); + +var Tel = dict(Str, Num); + +// costructor usage, `tel` is immutable +Tel({ jack: 4098, sape: 4139 }); + +var ReactKey = union([Str, Num]); + +ReactKey.is("a"); // => true +ReactKey.is(1); // => true +ReactKey.is(true); // => false + +ReactKey.dispatch = x => { + if (Str.is(x)) return Str; + if (Num.is(x)) return Num; + return Any; +}; + +// now you can do this without a fail +ReactKey("a"); + +// the value of a radio input where null = no selection +var Radio = maybe(Str); + +Radio.is("a"); // => true +Radio.is(null); // => true +Radio.is(1); // => false + +// add takes two `Num`s and returns a `Num` +var add = func([Num, Num], Num) + .of((x: number, y: number) => { return x + y; }); + +add("Hello", 2); // Raises error: Invalid `Hello` supplied to `Num` +add("Hello"); // Raises error: Invalid `Hello` supplied to `Num` + +add(1, 2); // Returns: 3 +add(1)(2); // Returns: 3 + +// An `A` takes a `Str` and returns an `Num` +func(Str, Num); + +// A `B` takes a `Func` (which takes a `Str` and returns a `Num`) and returns a `Str`. +func(func(Str, Num), Str); + +// An `ExcitedStr` is a `Str` containing an exclamation mark +var ExcitedStr = subtype(Str, s => { return s.indexOf("!") !== -1; }, "ExcitedStr"); + +// An `Exciter` takes a `Str` and returns an `ExcitedStr` +var Exciter = func(Str, ExcitedStr); + +// A `C` takes an `A`, a `B` and a `Str` and returns a `Num` +func([A, B, Str], Num); + +func(A, B).of(() => {}); + +var simpleQuestionator = Exciter.of((s: string) => { return s + "?"; }); +var simpleExciter = Exciter.of((s: string) => { return s + "!"; }); + +// Raises error: +// Invalid `Hello?` supplied to `ExcitedStr`, insert a valid value for the subtype +simpleQuestionator("Hello"); + +// Raises error: Invalid `1` supplied to `Str` +simpleExciter(1); + +// Returns: "Hello!" +simpleExciter("Hello"); + +// We can reasonably suggest that add has the following type signature +// add : Num -> Num -> Num +add = func([Num, Num], Num) + .of((x: number, y: number) => { return x + y }); + +add("Hello"); // As this raises: "Error: Invalid `Hello` supplied to `Num`" + +var add2 = add(2); +add2(1); // And this returns: 3 + +func(A, B).is(x); + +Exciter.is(simpleExciter); // Returns: true +Exciter.is(simpleQuestionator); // Returns: true + +var id = (x: number) => { return x; }; + +func([Num, Num], Num).is(func([Num, Num], Num).of(id)); // Returns: true +func([Num, Num], Num).is(func(Num, Num).of(id)); // Returns: false + +var p4 = new Point({x: 1, y: 2}); + +p4 = Point.update(p4, { x: { "$set": 3 } }); // => {x: 3, y: 2} + +var Type2 = dict(Str, Num); +var instance = Type2({ a: 1, b: 2 }); +Type2.update(instance, { $remove: ["a"] }); // => {b: 2} + +var Type3 = list(Num); +var instance2 = Type3([1, 2, 3, 4]); +Type3.update(instance2, { "$swap": { from: 1, to: 2 } }); // => [1, 3, 2, 4] + +t.options.onFail = message => { + return message; +}; + +t.format("Invalid argument `name` = `%s` supplied to `%s`", 1, "MyType"); + +t.getKind(Str); // => 'irreducible' +t.getKind(list(Str)); // => 'list' + +t.getFunctionName(t.getKind); // => 'getKind' +t.getFunctionName(() => { }); // => '' + +t.getTypeName(Str); + +t.mixin({ a: 1 }, { b: 2 }); // => {a: 1, b: 2} +t.mixin({ a: 1 }, { a: 2 }); // => fail! diff --git a/tcomb/tcomb.d.ts b/tcomb/tcomb.d.ts new file mode 100644 index 000000000..3c9197d86 --- /dev/null +++ b/tcomb/tcomb.d.ts @@ -0,0 +1,420 @@ +// Type definitions for tcomb v0.4 +// Project: http://gcanti.github.io/tcomb/guide/index.html +// Definitions by: Jed Mao +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module tcomb { + + export var options: { + onFail: (message: string) => void; + }; + + /** + * Like util.format in Node. + */ + export function format(format: string, ...values: any[]): string; + export function getKind(type: T): string; + /** + * Returns a function's name or displayName if specified; otherwise, + * fallbacks on '>'. + */ + export function getFunctionName(fn: Function): string; + export function getTypeName(type: T): string; + /** + * Safe version of mixin, properties can be overwritten. + */ + export function mixin(target: {}, source: {}, overwrite?: boolean): any; + export var slice: typeof Array.prototype.slice; + export function shallowCopy(x: T): T; + export function update(instance: any, spec: {}): T; + /** + * If an assert fails the debugger kicks in so you can inspect the stack + * and quickly find out what's wrong. + * @param message - Useful for debugging. Formatted with values like util.format in Node. + * @param values - Sequentially inserted into the message. + */ + export function assert(condition: boolean, message?: string, ...values: any[]): void; + export function fail(message?: string): void; + + interface T { + meta: { + /** + * The type kind, equal to "irreducible" for irreducible types. + */ + kind: string; + /** + * The type name. + */ + name: string; + }; + displayName: string; + is(value: any): boolean; + update(instance: any, spec: {}): T; + } + + interface TypePredicate { + (x: any): Bool_Instance; + } + + interface Any_Instance { + } + + interface Any_Static extends T { + new (value: any): Any_Instance; + (value: any): Any_Instance; + } + + export var Any: Any_Static; + + interface Nil_Instance { + } + + interface Nil_Static extends T { + new (value: any): Nil_Instance; + (value: any): Nil_Instance; + } + + export var Nil: Str_Static; + + interface Str_Instance extends String { + } + + interface Str_Static extends T { + new (value: string): Str_Instance; + (value: string): Str_Instance; + meta: { + /** + * The type kind, equal to "irreducible" for irreducible types. + */ + kind: string; + /** + * The type name. + */ + name: string; + /** + * The type predicate. + */ + is: TypePredicate; + }; + } + + export var Str: Str_Static; + + interface Num_Instance extends Number { + } + + interface Num_Static extends T { + new (value: number): Num_Instance; + (value: number): Num_Instance; + } + + export var Num: Num_Static; + + interface Bool_Instance extends Boolean { + } + + interface Bool_Static extends T { + new (value: boolean): Bool_Instance; + (value: boolean): Bool_Instance; + } + + export var Bool: Bool_Static; + + interface Arr_Instance extends Array { + } + + interface Arr_Static extends T { + new (value: any[]): Arr_Instance; + (value: any[]): Arr_Instance; + } + + export var Arr: Arr_Static; + + interface Obj_Instance extends Object { + } + + interface Obj_Static extends T { + new (value: Object): Obj_Instance; + (value: Object): Obj_Instance; + } + + export var Obj: Obj_Static; + + interface Func_Instance extends Function { + } + + interface Func_Static extends T { + new (value: Function): Func_Instance; + (value: Function): Func_Instance; + } + + export var Func: Func_Static; + + interface Err_Instance extends Error { + } + + interface Err_Static extends T { + new (value: Error): Err_Instance; + (value: Error): Err_Instance; + } + + export var Err: Err_Static; + + interface Re_Instance extends RegExp { + } + + interface Re_Static extends T { + new (value: RegExp): Re_Instance; + (value: RegExp): Re_Instance; + } + + export var Re: Re_Static; + + interface Dat_Instance extends Date { + } + + interface Dat_Static extends T { + new (value: Date): Dat_Instance; + (value: Date): Dat_Instance; + } + + export var Dat: Dat_Static; + + interface Type_Instance { + } + + interface Type_Static extends T { + new (value: any): Type_Instance; + (value: any): Type_Instance; + } + + export var Type: Type_Static; + + /** + * @param name - The type name. + * @param is - A predicate. + */ + export function irreducible(name: string, is: TypePredicate): T; + /** + * @param props - A hash whose keys are the field names and the values are the fields types. + * @param name - Useful for debugging purposes. + */ + export function struct(props: Object, name?: string): typeof Struct; + + export interface Struct_Static extends T { + new (value: any, mutable?: boolean): Struct_Instance; + (value: any, mutable?: boolean): Struct_Instance; + meta: { + kind: string; + name: string; + props: any[]; + }; + /** + * @param mixins - Contains the new props. + * @param name - Useful for debugging purposes. + */ + extend(mixins: Object, name?: string): Struct_Static; + /** + * @param mixins - Contains the new props. + * @param name - Useful for debugging purposes. + */ + extend(mixins: Struct_Static, name?: string): Struct_Static; + /** + * @param mixins - Contains the new props. + * @param name - Useful for debugging purposes. + */ + extend(mixins: Object[], name?: string): Struct_Static; + /** + * @param mixins - Contains the new props. + * @param name - Useful for debugging purposes. + */ + extend(mixins: Struct_Static[], name?: string): Struct_Static; + } + + interface Struct_Instance { + } + + export var Struct: Struct_Static; + + /** + * @param map - A hash whose keys are the enums (values are free). + * @param name - Useful for debugging purposes. + */ + export function enums(map: Object, name?: string): T; + export module enums { + /** + * @param keys - Array of enums. + * @param name - Useful for debugging purposes. + */ + export function of(keys: string[], name?: string): T; + /** + * @param keys - String of enums separated by spaces. + * @param name - Useful for debugging purposes. + */ + export function of(keys: string, name?: string): T; + } + + /** + * @param name - Useful for debugging purposes. + */ + export function union(types: T[], name?: string): Union_Static; + + interface Union_Static extends T { + new (value: any, mutable?: boolean): Union_Instance; + (value: any, mutable?: boolean): Union_Instance; + meta: { + kind: string; + name: string; + types: T[]; + }; + dispatch(x: any): T; + } + + interface Union_Instance { + } + + export var Union: Union_Static; + + /** + * @param type - The wrapped type. + * @param name - Useful for debugging purposes. + */ + export function maybe(type: T, name?: string): Maybe_Static; + + export interface Maybe_Static extends T { + new (value: any, mutable?: boolean): Maybe_Instance; + (value: any, mutable?: boolean): Maybe_Instance; + meta: { + kind: string; + name: string; + typee: T; + }; + } + + interface Maybe_Instance { + } + + export var Maybe: Maybe_Static; + + /** + * @param name - Useful for debugging purposes. + */ + export function tuple(types: T[], name?: string): Tuple_Static; + + interface Tuple_Static extends T { + new (value: any, mutable?: boolean): Tuple_Instance; + (value: any, mutable?: boolean): Tuple_Instance; + meta: { + kind: string; + name: string; + types: T[]; + }; + } + + interface Tuple_Instance { + } + + export var Tuple: Tuple_Static; + + /** + * Combines old types into a new one. + * @param type - A type already defined. + * @param name - Useful for debugging purposes. + */ + export function subtype(type: T, predicate: TypePredicate, name?: string): typeof Subtype; + + interface Subtype_Static extends T { + new (value: any, mutable?: boolean): Subtype_Instance; + (value: any, mutable?: boolean): Subtype_Instance; + meta: { + kind: string; + name: string; + type: T; + predicate: TypePredicate; + }; + } + + interface Subtype_Instance { + } + + export var Subtype: Subtype_Static; + + /** + * @param type - The type of list items. + * @param name - Useful for debugging purposes. + */ + export function list(type: T, name?: string): List_Static; + + interface List_Static extends T { + new (value: any, mutable?: boolean): List_Instance; + (value: any, mutable?: boolean): List_Instance; + meta: { + kind: string; + name: string; + 'type': T; + }; + } + + interface List_Instance { + } + + export var List: List_Static; + + /** + * @param domain - The type of keys. + * @param codomain - The type of values. + * @param name - Useful for debugging purposes. + */ + export function dict(domain: T, codomain: T, name?: string): Dict_Static; + + interface Dict_Static extends T { + new (value: any, mutable?: boolean): Dict_Instance; + (value: any, mutable?: boolean): Dict_Instance; + meta: { + kind: string; + name: string; + domain: T; + codomain: T; + }; + } + + interface Dict_Instance { + } + + export var Dict: Dict_Static; + + /** + * @param type - The type of the function's argument. + * @param codomain - The type of the function's return value. + * @param name - Useful for debugging purposes. + */ + export function func(domain: T, codomain: T, name?: string): Func_Static; + /** + * @param type - The list of types of the function's arguments. + * @param codomain - The type of the function's return value. + * @param name - Useful for debugging purposes. + */ + export function func(domain: T[], codomain: T, name?: string): Func_Static; + + interface Func_Static extends T { + new (value: any, mutable?: boolean): Func_Instance; + (value: any, mutable?: boolean): Func_Instance; + meta: { + kind: string; + name: string; + domain: any; + codomain: T; + }; + of(fn: Function): Function; + } + + interface Func_Instance { + } + + export var Func: Func_Static; + +} + +declare module "tcomb" { + export = tcomb; +}