text: 
  // Generated by Page Builder
  import Page from './Page';
  import _    from 'lodash';
  
  export default {
  
      $pages() {
          return Object.values(this).filter(page => page instanceof Page);
      },
  
      $blogs() {
          return this.$pages().filter(page => page.blog).sort(Page.compareDates);
      },
  
      $search(searchText) {
          const regex   = new RegExp(_.escapeRegExp(_.escape(searchText)), 'i');
          const results = [];
          for (const page of this.$pages()) {
              if (page.$searchRegex(regex)) {
                  results.push(page);
              }
          }
          return results;
      },
  
      api: new Page({
          name: 'api',
          content: "# Introduction\n\nNote if you just want a quick understanding of type-mark it is recommended you\nstart with the [Getting Started](/type-mark/index/#getting-started) section on\nthis site's homepage.\n\nThis page breaks down the internals of type-checker into 5 key sections.\n\n - **[Involved Examples](#involved-examples)** Some more intense examples than\n what appears in\n [Getting Started](/type-mark/index/#getting-started)\n - **[TypeState](#typestate)** A detailed look at the `TypeSate` object itself\n that makes type-mark tick\n - **[Extensions](#extensions)** Also referred to as tests or checks. This\n section details each extension individually\n - **[Modifiers](#modifiers)** A look at extension modifiers and how they stack\n together\n - **[Util](#util)** Overview of type-mark's utility library\n\n# Involved Examples\n\n## Creating a Regex Test\n\nRegular expressions are a common method of validation. type-mark does not\ninclude support for regex by default, but adding support is a straightforward\ntask.\n\n### Motivation\n\nBefore designing a regex interface for type-mark we should first consider what\npurpose it will serve, considering we have `/regex/.test` already. Here are a\ncouple benefits that may motivate us\n\n - Allows us to quickly modify our use of a given regex using type-mark's `not`,\n `arrayof`, `of`, `collapse`, and `assert` modifiers\n - Allows us to use regex validation in interfaces without having to create an\n anonymous function for every regex test\n\n### Implementation\n\nBelow is an implementation of regex support for type-mark with the test name\n`re`. The [.format](#formatasserted--array-found--array) is a method\nprovided by `TypeState` for creating default error messages. The first parameter\nappears in the *Asserted* section of the message and the second parameter appears\nin the *Found* section of the message.\n\n```lang:js-readonly\ntype.extendfn('re', function(regex, arg) {\n    return new RegExp('^' + regex.source + '$').test(arg);\n}, function(regex, arg) {\n    return this.format(['regex', regex], [this.type, arg]);\n});\n```\n\n### Usage\n\nThere are a variety of ways we might use this new test. For simple patterns\nwe can use the standard API.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype('aaaab').re(/a+b/)\n```\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype.re(/\\d+/, '1.1')\n```\n\nWe may wish to use this test as the basis for another test. We could use\n[extend](#extendname--string-test--function-message--mixed) to create a test for a specific regex. Let's imagine we wanted\nto validate a url.\n\n```lang:js-readonly\nvar reUrl = /^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*\\/?$/;\n\ntype.extend('url', type.re(reUrl));\n```\n\nWe can now validate urls using the standard type-mark API, as well as use it\nin interfaces. For instance you could define an interface like so\n\n```lang:js-readonly\nvar website = {\n    url    : type.url,\n    name   : type.string,\n    author : type.string,\n    hits   : type.integer\n};\n```\n\nWe can now use this interface to validate that our list of websites meets\nour expected format.\n\n```lang:js-readonly\ntype(websiteList).arrayof.implements(website)\n```\n\nIn this example we saw how type-mark treats user extensions as first class\ncitizens. Expanding type-mark is a process that builds on itself and is often\nself referential.\n\n## Adding a Nested Modiifer\n\ntype-mark provides several modifiers for introspecting objects and arrays,\nbut these only go one level deep. We will implement a nested modifier which\ninspects all values in a nested set of array/objects.\n\n### Motivation\n\nBefore creating a new modifiers we should first consider what purpose it will\nserve. Here are a couple benefits that may motivate us\n\n - Saves us time when creating interfaces with homogenous types\n - Allows us to filter out unwanted types, for instance we may want to check\n that a record does not contain any strings\n\n### Implementation\n\nWe will use recursion to check deeply nested objects. The first step is to\ncreate a function that will return the correct results. We will call this\nfunction `nest`. Let’s take a look at it\n\n```lang:js-readonly\nfunction nest(that, test, args, value) {\n    if(type(value).object) {\n        return Object.keys(value).every(function(i) {\n            return nest(that, test, args, value[i]);\n        });\n    }\n    return test.apply(that, args.concat([value]));\n}\n```\n\nLet's break this down line by line.\n\n```lang:js-readonly-nolines\nfunction nest(that, test, args, value) {\n```\n\nHere our function signature tells us what we are going to need to pass in later\nfrom our modifier. `that` is the current `TypeState` being resolved. `test` is the\ncheck that our modifier is modifying. `args` is an array of arguments that may\nneed to be passed to the test (such as with `instanceof`, `lengthof`, etc.). And\nfinally value is the value we want to know the nested result of.\n\n```lang:js-readonly-nolines\nif(type(value).object) {\n```\n\nIf value is an object (which includes Arrays) then we want to do our nested\ncheck. That is for every key in the object we want to check that its value also\npasses the nested check.\n\n```lang:js-readonly-nolines\nreturn Object.keys(value).every(function(i) {\n    return nest(that, test, args, value[i]);\n});\n```\n\nHere is the implementation of what we described above. For each item in our\nvalue we are just going to recurse into nest. `that`, `test`, and `args` will\nall remain the same, the only thing changing will be value!\n\n```lang:js-readonly-nolines\nreturn test.apply(that, args.concat([value]));\n```\n\nThis is our else case, when our value is not an Array or object. Calling a test\nfrom a modifier is not nearly as easy as `test(value)`. We have to make sure\nto pass the calling context (the that argument) as well as pass in the expected\narguments (hence why we concat value to the end of arguments). Even the `not`\nmodifier must use `apply` to achieve this.\n\nNow that we've broken down nest, all we have to do is write our modifier, which\nis as easy as calling the right part of type-mark's API and then returning a call\nto `nest`.\n\n```lang:js-readonly\ntype.modify('nested', function nested(test) {\n    return function() {\n\n        var that = this;\n        var args = type.util.toArray(arguments);\n        var value = args.pop();\n\n        return nest(that, test, args, value);\n    };\n});\n```\n\nLet's break this down too.\n\n```lang:js-readonly-nolines\ntype.modify('nested', function nested(test) {\n    return function() {\n```\n\nModifiers are added to type-mark using the [modify](#modify) function. It expects a name\nand a function which will take a test and return a new (modified) test. This is\nwhy the first thing we do inside our modifier is return a new function, this\nwill replace test in the type-mark resolution process. In fact there is a good\nchance that the test we are being passed has already been modified!\n\n```lang:js-readonly-nolines\nvar that = this;\nvar args = type.util.toArray(arguments);\nvar value = args.pop();\n```\n\nHere we are getting the required values for `nest`. Because all tests are called\nwith `this` as the current `TypeState`, that means that `this` in our function\nwill be a `TypeState` too since we are a test! So `this` will become `that`. `args`\nare just the arguments that got passed to our very own function, and the value\nwill be the final argument.\n\n```lang:js-readonly-nolines\nreturn nest(that, test, args, value);\n```\n\nFinally, we just call nest with our starting values.\n\n### Usage\n\nNested calls will work even with no nesting at all. This means we can call it\nwith primitive types and will be like there is no modifier at all\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(12).nested.number\n```\n\nIn the case of a flat array or object though, nested behaves a lot like `of`. In\nfact the code shown here is based off the implementation of `of`.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype([Math.PI]).nested.number\n```\n\nWhat makes it special is that it can weed out values that are a away\nfrom the surface\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype([[1, 2, 3, 4], { x : -1, y : 2.5, z : [0]}]).nested.number\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype([{ x : 12 }, { y : [42, ['string!']]}]).nested.number\n```\n\nIn this example, we saw how type-mark allows you to define your own modifiers.\nCreating modifiers is not as simple as extensions, but they are significantly\nmore powerful since they change the way all other tests behave.\n\n# TypeState\n\n`TypeState` is the core object that powers type-mark. It is instantiated\nindirectly through every call to `type`\n\n## `new TypeState(values : Array)`\n\n**values** is an array of values to test, where `values[0]` is used for\nmost tests and `values[...]` is used for tests with the collapse modifier.\n\n## `.value`\n\nThe first element of the array argument given to the `TypeState`\nconstructor. This will correspond to the first argument passed to `type`.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\nstate = type('value')\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\nstate.value\n```\n\n## `.type`\n\nThe type of the `.value`. This value is computed upon access and is\nequivalent to the result of `typeof` except that `null` will return\n`null`.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(Math.PI).type\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(null).type\n```\n\n## `.stack`\n\nAn array of strings representing the current modifier stack on the `TypeState`.\nThis value is computed upon access and is equivalent to mapping over `._stack`\nand replacing each modifier function with its name. Used by `.format`.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype().assert.not.arrayof.stack\n```\n\n## `._value`\n\nThe array of elements passed to the constructor of `TypeState`. Used by\nthe `collapse` modifier.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(1, 2, 3, 4)._value\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\nnew type.TypeState([1, 2, 3, 4])._value\n```\n\n## `._stack`\n\nThe current modifier stack on the `TypeState` instance. Each modifier is passed\nthe result of the return value of the previous modifier (starting right to left)\nwith the first modifier receiving the expected test.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype().assert.not.arrayof._stack\n```\n\n## `._args`\n\nStores the arguments used when calling an extension that takes parameters.\n\n## `._return`\n\nUsed by modifiers to modify the return result for when a test passed. By default\nthis is `true`, but in the case of `collapse` this is modified to be the first\nmatching argument.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\nstate = type(4)\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\nstate._return = \"Wha???\"\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\nstate.number\n```\n\n## `._message`\n\nThe user specified string or function set by `.message()` used in place of the\ndefault or extension specified `TypeError` message.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\nstate = type(4)\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\nstate._message = function() { return 'overridden'; }\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\nstate.assert.string\n```\n\n## `.resolve(name : string, test : function)`\n\n**name** the name of the extension test\n\n**test** the extension test function\n\nResolves a `TypeState` to either `._return` or `false`. The primary computing\nfunction behind type-mark. Does *not* directly modify the modifier stack.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(4).not.resolve('string', type.string)\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(5).arrayof.resolve('instanceof', type.min(4))\n```\n\n## `.result(test : function)`\n\n**test** the test to compute the result of\n\n**returns** the return value of the given test\n\nA function for computing the result of an extension on a given `TypeState`\nobject outside the context of modifiers, but within the context of its\ninitial value and arguments. Used internally for consistency.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(/regex/).not.result(type.instanceof(RegExp))\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype().result(type.number)\n```\n\n## `.message(message : mixed)`\n\n**message** the overrideing message string or function\n\n**returns** the `TypeState` object for chaining\n\nA function that sets `._message`. If a string is passed to `.message` this\nstring will be used for any `TypeError`s that occur. If a function is passed it\nwill be called with the same arguments as the current test and used instead of\nthe default or extension specified `TypeError` message.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(null).message(':(').assert.exists\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(null).message(function(arg) { return 'Oops ' + arg; }).assert.exists\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype().message(function() { return 'Oops' })._message()\n```\n\n## `.format(asserted : Array, found : Array)`\n\n**asserted** an Array of asserted values/names\n\n**found** an Array of found values/names\n\n**returns** the formatted error string\n\nA function the combines the current modifier stack with a list of asserted and\nfound values to create an error message in the default format.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype().format(['hello', 'world'], ['maybe?', undefined])\n```\n\n# Extensions\n\nExtensions, also known as tests or checks, are what make type-mark useful.\n\n## `.extend(name : string, test : function, [message : mixed])`\n\n**name** the name of the new test/check\n\n**test** the test function\n\n**message** an optional argument to specify the default error message\n\nExtends `TypeState` with a new test function that will be called when accessed.\nThis function manages all the details required to ensure that the new test\nis correctly modified by modifiers. Even though the test is a function, it is\nrun when it as accessed as a property. This is done using\n[defineProperty](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).\n\nThe test function should expect one argument (the current value being tested)\nand should always return a boolean result.\n\nAs an example, here is the implementation of the `array` extension\n\n```lang:js-readonly\ntype.extend('array', Array.isArray);\n```\n\nBy default a new extension's error message will use the format\n```readonly-nolines\nUncaught TypeError: Expected <ExtenstionName> -- Found : <type> <value>\n```\n\nTo provide a custom dynamic error message see\n[.format](#formatasserted--array-found--array). Or alternatively access\n[.stack](#stack) directly and create an appropriate error message. The error\nmessage function is called with the same arguments as the test function,\n\n## `.extendfn(name : string, test : function, [message : function])`\n\n**name** the name of the new test/check\n\n**test** the test function\n\n**message** an optional argument to specify the default error message\n\nExtends `TypeState` with a new test function that expects arguments. This\nfunction manages all the details required to ensure that the new test is\ncorrectly modified by modifiers. Additionally, the test function will be\nconverted to a curried function when accessed using type-mark's alternate\nsyntax.\n\nThe test function can expect any number of arguments greater than or equal to\none. The final argument received by the function will be the value being tested.\nThis is to ensure that currying works as expected. The function should always\nreturn a boolean result.\n\nAs an example, here is the implementation of the `lengthof` extension\n\n```lang:js-readonly\ntype.extendfn('lengthof', function(n, arg) {\n    type(n).assert.number;\n    return type.util.length(arg) === n;\n}, function(n, arg) {\n    return this.format(\n        ['lengthof', n],\n        [this.type, 'lengthof', String(type.util.length(arg))]\n    );\n});\n```\n\nIt is more common for `extendfn` extensions to modify their error messages in\norder to display the arguments passed to them. The above creates error messages\nlike the following\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype([1, 2, 3]).assert.not.lengthof(3)\n```\n\nTo provide a custom dynamic error message see\n[.format](#formatasserted--array-found--array). Or alternatively access\n[.stack](#stack) directly and create an appropriate error message. The error\nmessage function is called with the same arguments as the test function,\n\n## `and(...checks : function)`\n\n**checks** any number of test functions\n\nReturns true if the all the checks provided to `and` pass for the current\nvalue. When using the standard syntax any number of test functions can be\npassed, but when using the alternate syntax in an interface, only two checks\nmay be provided. This is to prevent currying from continuing indefinitely.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype([1, 2, 3]).and(type.array, type.lengthof(3), type.exists)\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype({ x : [1, 2, 3] }).implements({ x : type.and(type.array, type.lengthof(3)) })\n```\n\nIf you try to use `and` as a function with more than 2 arguments, you will get\nan error message\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype({ x : [1, 2, 3]}).implements({ x : type.and(\n    type.array,\n    type.lengthof(3),\n    type.exists\n)})\n```\n\n## `array`\n\nReturns true if the current value is an array.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype([1, 2, 3]).array\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype('string').array\n```\n\n## `boolean`\n\nReturns true if the current value is a boolean.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(true).boolean\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(false).boolean\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(0).boolean\n```\n\n## `empty`\n\nReturns true if the current value is either an empty array, object, or string.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype([]).empty\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype({}).empty\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype('').empty\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(' ').empty\n```\n\n## `even`\n\nReturns true if the current value is an even integer.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(-2).even\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(4.04).even\n```\n\n## `exists`\n\nReturns true if the current value is neither `null` nor `undefined`.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype([]).exists\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(null).exists\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(undefined).exists\n```\n\n## `function`\n\nReturns true if the current value is a function.\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(function() {}).function\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(Array).function\n```\n\n```lang:js-readonly-evaluator:jsEvaluator-immediate\ntype(new Array()).function\n```\n\n## `implements(interface : object)`\n\n**interface** an object of nested functions representing an interface\n\nReturns true if the current value implements the given interface. An interface\nshould be composed exclusively of objects and functions. Each key in the object\nshould map to either a validation function (that when failing means the current\nvalue does not implement the interface) or a nested object, representing a\nnested object in the current value itself.\n\nBelow is an example interface\n\n```lang:js-readonly\nvar myInterface = {\n    name : type.string,\n    age  : type.integer,\n    coordinate : {\n        x : type.number,\n        y : type.number,\n        z : type.number\n    }\n};\n```\n\nBased on the interface above we can test to see if a or b implement the\ninterface.\n\n```lang:js-readonly\nvar a = {\n    name : 'bear',\n    age  : 14.5,\n    coordinate : {\n       x : 0.0,\n       y : 1.1, \n       z : 0.1\n    }\n}\nvar b = {\n    name : 'bird',\n    age  : 1,\n    coordinate : {\n        x : 0.0,\n        y : 0.0,\n        z : 14.0,\n        flag : true\n    }\n}\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(a).implements(myInterface)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(b).implements(myInterface)\n```\n\n`a` due to `age` being a float rather than an integer. `b` succeeds because\nadditional properties are ignored.\n\nInterfaces may also be nested within interfaces. For example\n\n```lang:js-readonly\nvar nestedInterface = {\n    coordinates : type.arrayof.implements({\n        x : type.number,\n        y : type.number\n    })\n};\n```\n\nis a valid interface that checks if the supplied object contains a property\ncoordinates that is an array of `{x, y}` objects.\n\nUser defined validation functions may also be used in an interface, for instance\n\n```lang:js-readonly\nvar interface = {\n    three : function isThree(arg) {\n        return arg === 3 || /^(3|three|iii)$/i.test(arg);\n    }\n};\n```\n\n## `instanceof(constructor : function)`\n\n**constructor** the object constructor\n\nReturns true if the current value was constructed by `constructor`.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(new Date).instanceof(Date)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype([]).instanceof(Date)\n```\n\n## `integer`\n\nReturns true if the current value is an \"integer\" that is it is equal to the\nfloored version of itself.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(3).integer\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(3.14).integer\n```\n\n## `lengthof(n : number)`\n\n**n** the desired number\n\nReturns true if the current value is either an array, string or object with `n`\nkeys.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype([1, 2, 3]).lengthof(3)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype('hi!').lengthof(3)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype({ x : 'x' , y : 'y', z : 'z' }).lengthof(3)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype({}).lengthof(3)\n```\n\n## `max(n : number)`\n\n**n** the maximum number\n\nReturns true if the current value is less than or equal to max.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(Math.E).max(Math.PI)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(0).max(-1)\n```\n\n## `min(n : number)`\n\n**n** the minimum number\n\nReturns true if the current value is greater than or equal to min.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(Math.PI).min(Math.E)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(-1).min(0)\n```\n\n## `native`\n\nReturns true if the current value is a native function. Based off the\nimplementation of [lodash's](https://lodash.com/) isNative function.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(Array).native\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype({}).native\n```\n\n## `negative`\n\nReturns true if the current value is a negative number.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(-3.14).negative\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(-12000).negative\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(0).negative\n```\n\n## `number`\n\nReturns true if the current value is a number.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(Math.PI).number\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype([]).number\n```\n\n## `object`\n\nReturns true if the current value is an object (and not `null`).\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype([]).object\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(/regex/).object\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(null).object\n```\n\n## `odd`\n\nReturns true if the current value is an odd integer.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(17).odd\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(1.04).odd\n```\n\n## `or(...checks : function)`\n\n**checks** any number of test functions\n\nReturns true if the any of the checks provided to `or` pass for the current\nvalue. When using the standard syntax any number of test functions can be\npassed, but when using the alternate syntax in an interface, only two checks\nmay be provided. This is to prevent currying from continuing indefinitely.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype('test').or(type.number, type.boolean, type.string)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype({ x : [1, 2, 3] }).implements({ x : type.or(type.function, type.lengthof(3)) })\n```\n\nIf you try to use `or` as a function with more than 2 arguments, you will get\nan error message\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype({ x : [1, 2, 3] }).implements({ x : type.or(\n    type.function,\n    type.lengthof(3),\n    type.exists\n)})\n```\n\n## `positive`\n\nReturns true if the current value is a positive number.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(3.14).positive\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(0).positive\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(-42).positive\n```\n\n## `range(min : number, max : number)`\n\n**min** the minimum number\n\n**max** the maximum number\n\nReturns true if the current value is greater than or equal to min and strictly\nless than the maximum.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(97).range(0, 100)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(-42).range(-50, 25)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(10).range(0, 10)\n```\n\n## `string`\n\nReturns true if the current value is a string.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype('string').string\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(true).string\n```\n\n## `symbol`\n\nReturns true if the current value is a symbol.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(Symbol()).symbol\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype('string').symbol\n```\n\n## `undefined`\n\nReturns true if the current value is `undefined`.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(void 0).undefined\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype([]).undefined\n```\n\n# Modifiers\n\nModifiers wrap around extensions, changing their default behaviour. Modifiers are\napplied in a stack, last in first out, basis. For example\n\n```lang:js-readonly\ntype(x).arrayof.not.number\n```\n\nchecks that x is an array of non-number elements whereas\n\n```lang:js-readonly\ntype(x).not.arrayof.number\n```\n\nchecks that x is not an array of numbers.\n\n## `.modify(name : string, mod : function)`\n\n**name** the name of the new modifier\n\n**mod** the modifier function\n\nDefines a new modifier. In addition to the `name` argument, the modifier\nfunction's `.name` property should also be set to an appropriate value as it\nis used in default error messages.\n\nThe modifier function is expected to accept a test function, for example the\narray extension's test function `Array.isArray` and return a new modified test.\nThe modifier is expected to provide all arguments it received to the original\ntest function if appropriate, include the `this` value.\n\nAs an example, here is the implementation of the `not` modifier\n\n```lang:js-readonly\ntype.modify('not', function not(test) {\n    return function() {\n        return !test.apply(this, arguments);\n    };\n});\n```\n\n## `arrayof`\n\nModifies the test function to return true only if the current value is an array\nof values that all pass the test.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype([1, 2, 3]).arrayof.number\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype({ 0 : 1, 1 : 2, 2 : 3 }).arrayof.number\n```\n\n## `assert`\n\nModifies the test function to throw a `TypeError` if the test fails.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(42).assert.string\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype('string').assert.not.string\n```\n\n## `collapse`\n\nModifies the test function to be called on all values passed to type, returning\nthe first value that passes the test. Returns false otherwise.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype('string', {}, [], 42, true, Math.PI).collapse.number\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(1, function() {}, []).collapse.string\n```\n\n**Note** Collapse does not support the alternate calling syntax.\n\n## `maybe`\n\nModifies the test function to return true for null and undefined values.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(null).maybe.number\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(12).maybe.number\n```\n\n## `not`\n\nModifies the test function, negating its result.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype('string').not.number\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(Math.PI).not.exists\n```\n\n## `of`\n\nSimilar to [arrayof]($arrayof) but supports all objects.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype({ 0 : 1, 1 : 2, 2 : 3 }).arrayof.number\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype([1, 2, 3]).arrayof.number\n```\n\n# Util\n\ntype-mark comes packed with a small utility library for common tasks needed\nelsewhere by the API.\n\n## `.util.define(obj : object, name : string, fn : function)`\n\n**object** the object to define a property on\n\n**name** the name of the property\n\n**fn** the function that returns the value of that property\n\nDefines a readonly property on an object. Used to simplify calling\n[defineProperty](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).\n\n```lang:js-readonly\nobj = {}\ntype.util.define(obj, 'x', function() { return true; })\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\nobj.x\n```\n\n## `.util.toArray(arg : mixed)`\n\n**arg** an array-like object\n\n**returns** an array containing the values of the array-like object\n\nUsed to convert `arguments` to an array, or similar objects.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype.util.toArray({ 0 : 1, 1 : 2, 2 : 3, length : 3 })\n```\n\n## `.util.length(arg : mixed)`\n\n**arg** a value to get the length of\n\n**returns** the length of the value or undefined if not applicable\n\nReturns a meaningful length value for a given argument. For arrays and strings\nthis means `.length`. For objects this means the number of key value pairs they\ncontain (excluding Symbols). For all other values `undefined` is returned.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype.util.length([1, 2, 3])\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype.util.length('Hello World!')\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype.util.length({ x : 'x', y : 'y' })\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype.util.length(12)\n```\n\n## `.util.curry(fn : function, [arity : number])`\n\n**fn** the function to curry\n\n**arity** an optional argument specifying the arity of the function\n\n**returns** the curried function\n\nCurries a function so that if it receives less than the functions's arity in\narguments it returns a new function expecting arity minus the number of\narguments received arguments. The returned function will also behave in this\nway.\n\nBy default the `.length` property of the function is used for arity.\n\nBased off the implementation explained\n[here](http://blog.carbonfive.com/2015/01/14/gettin-freaky-functional-wcurried-javascript/).\n\n```lang:js-readonly\nfn = type.util.curry(function(a, b, c) { return a + b + c; })\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\nfn(1)(2)(3)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\nfn(1, 2)(3)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\nfn(1)(2, 3)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\nfn(1, 2, 3)\n```",
          plainTxt: 'Introduction\nNote if you just want a quick understanding of type-mark it is recommended you\nstart with the Getting Started section on\nthis site&amp;#39;s homepage.\nThis page breaks down the internals of type-checker into 5 key sections.\nInvolved Examples Some more intense examples than\nwhat appears in\nGetting Started\nTypeState A detailed look at the TypeSate object itself\nthat makes type-mark tick\nExtensions Also referred to as tests or checks. This\nsection details each extension individually\nModifiers A look at extension modifiers and how they stack\ntogether\nUtil Overview of type-mark&amp;#39;s utility library\n\nInvolved Examples\nCreating a Regex Test\nRegular expressions are a common method of validation. type-mark does not\ninclude support for regex by default, but adding support is a straightforward\ntask.\nMotivation\nBefore designing a regex interface for type-mark we should first consider what\npurpose it will serve, considering we have /regex/.test already. Here are a\ncouple benefits that may motivate us\nAllows us to quickly modify our use of a given regex using type-mark&amp;#39;s not,\narrayof, of, collapse, and assert modifiers\nAllows us to use regex validation in interfaces without having to create an\nanonymous function for every regex test\n\nImplementation\nBelow is an implementation of regex support for type-mark with the test name\nre. The .format is a method\nprovided by TypeState for creating default error messages. The first parameter\nappears in the Asserted section of the message and the second parameter appears\nin the Found section of the message.\ntype.extendfn(&#39;re&#39;, function(regex, arg) {\n    return new RegExp(&#39;^&#39; + regex.source + &#39;$&#39;).test(arg);\n}, function(regex, arg) {\n    return this.format([&#39;regex&#39;, regex], [this.type, arg]);\n});\nUsage\nThere are a variety of ways we might use this new test. For simple patterns\nwe can use the standard API.\ntype(&#39;aaaab&#39;).re(/a+b/)\ntype.re(/\\d+/, &#39;1.1&#39;)\nWe may wish to use this test as the basis for another test. We could use\nextend to create a test for a specific regex. Let&amp;#39;s imagine we wanted\nto validate a url.\nvar reUrl = /^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*\\/?$/;\n\ntype.extend(&#39;url&#39;, type.re(reUrl));\nWe can now validate urls using the standard type-mark API, as well as use it\nin interfaces. For instance you could define an interface like so\nvar website = {\n    url    : type.url,\n    name   : type.string,\n    author : type.string,\n    hits   : type.integer\n};\nWe can now use this interface to validate that our list of websites meets\nour expected format.\ntype(websiteList).arrayof.implements(website)\nIn this example we saw how type-mark treats user extensions as first class\ncitizens. Expanding type-mark is a process that builds on itself and is often\nself referential.\nAdding a Nested Modiifer\ntype-mark provides several modifiers for introspecting objects and arrays,\nbut these only go one level deep. We will implement a nested modifier which\ninspects all values in a nested set of array/objects.\nMotivation\nBefore creating a new modifiers we should first consider what purpose it will\nserve. Here are a couple benefits that may motivate us\nSaves us time when creating interfaces with homogenous types\nAllows us to filter out unwanted types, for instance we may want to check\nthat a record does not contain any strings\n\nImplementation\nWe will use recursion to check deeply nested objects. The first step is to\ncreate a function that will return the correct results. We will call this\nfunction nest. Let’s take a look at it\nfunction nest(that, test, args, value) {\n    if(type(value).object) {\n        return Object.keys(value).every(function(i) {\n            return nest(that, test, args, value[i]);\n        });\n    }\n    return test.apply(that, args.concat([value]));\n}\nLet&amp;#39;s break this down line by line.\nfunction nest(that, test, args, value) {\nHere our function signature tells us what we are going to need to pass in later\nfrom our modifier. that is the current TypeState being resolved. test is the\ncheck that our modifier is modifying. args is an array of arguments that may\nneed to be passed to the test (such as with instanceof, lengthof, etc.). And\nfinally value is the value we want to know the nested result of.\nif(type(value).object) {\nIf value is an object (which includes Arrays) then we want to do our nested\ncheck. That is for every key in the object we want to check that its value also\npasses the nested check.\nreturn Object.keys(value).every(function(i) {\n    return nest(that, test, args, value[i]);\n});\nHere is the implementation of what we described above. For each item in our\nvalue we are just going to recurse into nest. that, test, and args will\nall remain the same, the only thing changing will be value!\nreturn test.apply(that, args.concat([value]));\nThis is our else case, when our value is not an Array or object. Calling a test\nfrom a modifier is not nearly as easy as test(value). We have to make sure\nto pass the calling context (the that argument) as well as pass in the expected\narguments (hence why we concat value to the end of arguments). Even the not\nmodifier must use apply to achieve this.\nNow that we&amp;#39;ve broken down nest, all we have to do is write our modifier, which\nis as easy as calling the right part of type-mark&amp;#39;s API and then returning a call\nto nest.\ntype.modify(&#39;nested&#39;, function nested(test) {\n    return function() {\n\n        var that = this;\n        var args = type.util.toArray(arguments);\n        var value = args.pop();\n\n        return nest(that, test, args, value);\n    };\n});\nLet&amp;#39;s break this down too.\ntype.modify(&#39;nested&#39;, function nested(test) {\n    return function() {\nModifiers are added to type-mark using the modify function. It expects a name\nand a function which will take a test and return a new (modified) test. This is\nwhy the first thing we do inside our modifier is return a new function, this\nwill replace test in the type-mark resolution process. In fact there is a good\nchance that the test we are being passed has already been modified!\nvar that = this;\nvar args = type.util.toArray(arguments);\nvar value = args.pop();\nHere we are getting the required values for nest. Because all tests are called\nwith this as the current TypeState, that means that this in our function\nwill be a TypeState too since we are a test! So this will become that. args\nare just the arguments that got passed to our very own function, and the value\nwill be the final argument.\nreturn nest(that, test, args, value);\nFinally, we just call nest with our starting values.\nUsage\nNested calls will work even with no nesting at all. This means we can call it\nwith primitive types and will be like there is no modifier at all\ntype(12).nested.number\nIn the case of a flat array or object though, nested behaves a lot like of. In\nfact the code shown here is based off the implementation of of.\ntype([Math.PI]).nested.number\nWhat makes it special is that it can weed out values that are a away\nfrom the surface\ntype([[1, 2, 3, 4], { x : -1, y : 2.5, z : [0]}]).nested.number\ntype([{ x : 12 }, { y : [42, [&#39;string!&#39;]]}]).nested.number\nIn this example, we saw how type-mark allows you to define your own modifiers.\nCreating modifiers is not as simple as extensions, but they are significantly\nmore powerful since they change the way all other tests behave.\nTypeState\nTypeState is the core object that powers type-mark. It is instantiated\nindirectly through every call to type\nnew TypeState(values : Array)\nvalues is an array of values to test, where values[0] is used for\nmost tests and values[...] is used for tests with the collapse modifier.\n.value\nThe first element of the array argument given to the TypeState\nconstructor. This will correspond to the first argument passed to type.\nstate = type(&#39;value&#39;)\nstate.value\n.type\nThe type of the .value. This value is computed upon access and is\nequivalent to the result of typeof except that null will return\nnull.\ntype(Math.PI).type\ntype(null).type\n.stack\nAn array of strings representing the current modifier stack on the TypeState.\nThis value is computed upon access and is equivalent to mapping over ._stack\nand replacing each modifier function with its name. Used by .format.\ntype().assert.not.arrayof.stack\n._value\nThe array of elements passed to the constructor of TypeState. Used by\nthe collapse modifier.\ntype(1, 2, 3, 4)._value\nnew type.TypeState([1, 2, 3, 4])._value\n._stack\nThe current modifier stack on the TypeState instance. Each modifier is passed\nthe result of the return value of the previous modifier (starting right to left)\nwith the first modifier receiving the expected test.\ntype().assert.not.arrayof._stack\n._args\nStores the arguments used when calling an extension that takes parameters.\n._return\nUsed by modifiers to modify the return result for when a test passed. By default\nthis is true, but in the case of collapse this is modified to be the first\nmatching argument.\nstate = type(4)\nstate._return = &quot;Wha???&quot;\nstate.number\n._message\nThe user specified string or function set by .message() used in place of the\ndefault or extension specified TypeError message.\nstate = type(4)\nstate._message = function() { return &#39;overridden&#39;; }\nstate.assert.string\n.resolve(name : string, test : function)\nname the name of the extension test\ntest the extension test function\nResolves a TypeState to either ._return or false. The primary computing\nfunction behind type-mark. Does not directly modify the modifier stack.\ntype(4).not.resolve(&#39;string&#39;, type.string)\ntype(5).arrayof.resolve(&#39;instanceof&#39;, type.min(4))\n.result(test : function)\ntest the test to compute the result of\nreturns the return value of the given test\nA function for computing the result of an extension on a given TypeState\nobject outside the context of modifiers, but within the context of its\ninitial value and arguments. Used internally for consistency.\ntype(/regex/).not.result(type.instanceof(RegExp))\ntype().result(type.number)\n.message(message : mixed)\nmessage the overrideing message string or function\nreturns the TypeState object for chaining\nA function that sets ._message. If a string is passed to .message this\nstring will be used for any TypeErrors that occur. If a function is passed it\nwill be called with the same arguments as the current test and used instead of\nthe default or extension specified TypeError message.\ntype(null).message(&#39;:(&#39;).assert.exists\ntype(null).message(function(arg) { return &#39;Oops &#39; + arg; }).assert.exists\ntype().message(function() { return &#39;Oops&#39; })._message()\n.format(asserted : Array, found : Array)\nasserted an Array of asserted values/names\nfound an Array of found values/names\nreturns the formatted error string\nA function the combines the current modifier stack with a list of asserted and\nfound values to create an error message in the default format.\ntype().format([&#39;hello&#39;, &#39;world&#39;], [&#39;maybe?&#39;, undefined])\nExtensions\nExtensions, also known as tests or checks, are what make type-mark useful.\n.extend(name : string, test : function, [message : mixed])\nname the name of the new test/check\ntest the test function\nmessage an optional argument to specify the default error message\nExtends TypeState with a new test function that will be called when accessed.\nThis function manages all the details required to ensure that the new test\nis correctly modified by modifiers. Even though the test is a function, it is\nrun when it as accessed as a property. This is done using\ndefineProperty.\nThe test function should expect one argument (the current value being tested)\nand should always return a boolean result.\nAs an example, here is the implementation of the array extension\ntype.extend(&#39;array&#39;, Array.isArray);\nBy default a new extension&amp;#39;s error message will use the format\nUncaught TypeError: Expected &lt;ExtenstionName&gt; -- Found : &lt;type&gt; &lt;value&gt;\nTo provide a custom dynamic error message see\n.format. Or alternatively access\n.stack directly and create an appropriate error message. The error\nmessage function is called with the same arguments as the test function,\n.extendfn(name : string, test : function, [message : function])\nname the name of the new test/check\ntest the test function\nmessage an optional argument to specify the default error message\nExtends TypeState with a new test function that expects arguments. This\nfunction manages all the details required to ensure that the new test is\ncorrectly modified by modifiers. Additionally, the test function will be\nconverted to a curried function when accessed using type-mark&amp;#39;s alternate\nsyntax.\nThe test function can expect any number of arguments greater than or equal to\none. The final argument received by the function will be the value being tested.\nThis is to ensure that currying works as expected. The function should always\nreturn a boolean result.\nAs an example, here is the implementation of the lengthof extension\ntype.extendfn(&#39;lengthof&#39;, function(n, arg) {\n    type(n).assert.number;\n    return type.util.length(arg) === n;\n}, function(n, arg) {\n    return this.format(\n        [&#39;lengthof&#39;, n],\n        [this.type, &#39;lengthof&#39;, String(type.util.length(arg))]\n    );\n});\nIt is more common for extendfn extensions to modify their error messages in\norder to display the arguments passed to them. The above creates error messages\nlike the following\ntype([1, 2, 3]).assert.not.lengthof(3)\nTo provide a custom dynamic error message see\n.format. Or alternatively access\n.stack directly and create an appropriate error message. The error\nmessage function is called with the same arguments as the test function,\nand(...checks : function)\nchecks any number of test functions\nReturns true if the all the checks provided to and pass for the current\nvalue. When using the standard syntax any number of test functions can be\npassed, but when using the alternate syntax in an interface, only two checks\nmay be provided. This is to prevent currying from continuing indefinitely.\ntype([1, 2, 3]).and(type.array, type.lengthof(3), type.exists)\ntype({ x : [1, 2, 3] }).implements({ x : type.and(type.array, type.lengthof(3)) })\nIf you try to use and as a function with more than 2 arguments, you will get\nan error message\ntype({ x : [1, 2, 3]}).implements({ x : type.and(\n    type.array,\n    type.lengthof(3),\n    type.exists\n)})\narray\nReturns true if the current value is an array.\ntype([1, 2, 3]).array\ntype(&#39;string&#39;).array\nboolean\nReturns true if the current value is a boolean.\ntype(true).boolean\ntype(false).boolean\ntype(0).boolean\nempty\nReturns true if the current value is either an empty array, object, or string.\ntype([]).empty\ntype({}).empty\ntype(&#39;&#39;).empty\ntype(&#39; &#39;).empty\neven\nReturns true if the current value is an even integer.\ntype(-2).even\ntype(4.04).even\nexists\nReturns true if the current value is neither null nor undefined.\ntype([]).exists\ntype(null).exists\ntype(undefined).exists\nfunction\nReturns true if the current value is a function.\ntype(function() {}).function\ntype(Array).function\ntype(new Array()).function\nimplements(interface : object)\ninterface an object of nested functions representing an interface\nReturns true if the current value implements the given interface. An interface\nshould be composed exclusively of objects and functions. Each key in the object\nshould map to either a validation function (that when failing means the current\nvalue does not implement the interface) or a nested object, representing a\nnested object in the current value itself.\nBelow is an example interface\nvar myInterface = {\n    name : type.string,\n    age  : type.integer,\n    coordinate : {\n        x : type.number,\n        y : type.number,\n        z : type.number\n    }\n};\nBased on the interface above we can test to see if a or b implement the\ninterface.\nvar a = {\n    name : &#39;bear&#39;,\n    age  : 14.5,\n    coordinate : {\n       x : 0.0,\n       y : 1.1, \n       z : 0.1\n    }\n}\nvar b = {\n    name : &#39;bird&#39;,\n    age  : 1,\n    coordinate : {\n        x : 0.0,\n        y : 0.0,\n        z : 14.0,\n        flag : true\n    }\n}\ntype(a).implements(myInterface)\ntype(b).implements(myInterface)\na due to age being a float rather than an integer. b succeeds because\nadditional properties are ignored.\nInterfaces may also be nested within interfaces. For example\nvar nestedInterface = {\n    coordinates : type.arrayof.implements({\n        x : type.number,\n        y : type.number\n    })\n};\nis a valid interface that checks if the supplied object contains a property\ncoordinates that is an array of {x, y} objects.\nUser defined validation functions may also be used in an interface, for instance\nvar interface = {\n    three : function isThree(arg) {\n        return arg === 3 || /^(3|three|iii)$/i.test(arg);\n    }\n};\ninstanceof(constructor : function)\nconstructor the object constructor\nReturns true if the current value was constructed by constructor.\ntype(new Date).instanceof(Date)\ntype([]).instanceof(Date)\ninteger\nReturns true if the current value is an &amp;quot;integer&amp;quot; that is it is equal to the\nfloored version of itself.\ntype(3).integer\ntype(3.14).integer\nlengthof(n : number)\nn the desired number\nReturns true if the current value is either an array, string or object with n\nkeys.\ntype([1, 2, 3]).lengthof(3)\ntype(&#39;hi!&#39;).lengthof(3)\ntype({ x : &#39;x&#39; , y : &#39;y&#39;, z : &#39;z&#39; }).lengthof(3)\ntype({}).lengthof(3)\nmax(n : number)\nn the maximum number\nReturns true if the current value is less than or equal to max.\ntype(Math.E).max(Math.PI)\ntype(0).max(-1)\nmin(n : number)\nn the minimum number\nReturns true if the current value is greater than or equal to min.\ntype(Math.PI).min(Math.E)\ntype(-1).min(0)\nnative\nReturns true if the current value is a native function. Based off the\nimplementation of lodash&amp;#39;s isNative function.\ntype(Array).native\ntype({}).native\nnegative\nReturns true if the current value is a negative number.\ntype(-3.14).negative\ntype(-12000).negative\ntype(0).negative\nnumber\nReturns true if the current value is a number.\ntype(Math.PI).number\ntype([]).number\nobject\nReturns true if the current value is an object (and not null).\ntype([]).object\ntype(/regex/).object\ntype(null).object\nodd\nReturns true if the current value is an odd integer.\ntype(17).odd\ntype(1.04).odd\nor(...checks : function)\nchecks any number of test functions\nReturns true if the any of the checks provided to or pass for the current\nvalue. When using the standard syntax any number of test functions can be\npassed, but when using the alternate syntax in an interface, only two checks\nmay be provided. This is to prevent currying from continuing indefinitely.\ntype(&#39;test&#39;).or(type.number, type.boolean, type.string)\ntype({ x : [1, 2, 3] }).implements({ x : type.or(type.function, type.lengthof(3)) })\nIf you try to use or as a function with more than 2 arguments, you will get\nan error message\ntype({ x : [1, 2, 3] }).implements({ x : type.or(\n    type.function,\n    type.lengthof(3),\n    type.exists\n)})\npositive\nReturns true if the current value is a positive number.\ntype(3.14).positive\ntype(0).positive\ntype(-42).positive\nrange(min : number, max : number)\nmin the minimum number\nmax the maximum number\nReturns true if the current value is greater than or equal to min and strictly\nless than the maximum.\ntype(97).range(0, 100)\ntype(-42).range(-50, 25)\ntype(10).range(0, 10)\nstring\nReturns true if the current value is a string.\ntype(&#39;string&#39;).string\ntype(true).string\nsymbol\nReturns true if the current value is a symbol.\ntype(Symbol()).symbol\ntype(&#39;string&#39;).symbol\nundefined\nReturns true if the current value is undefined.\ntype(void 0).undefined\ntype([]).undefined\nModifiers\nModifiers wrap around extensions, changing their default behaviour. Modifiers are\napplied in a stack, last in first out, basis. For example\ntype(x).arrayof.not.number\nchecks that x is an array of non-number elements whereas\ntype(x).not.arrayof.number\nchecks that x is not an array of numbers.\n.modify(name : string, mod : function)\nname the name of the new modifier\nmod the modifier function\nDefines a new modifier. In addition to the name argument, the modifier\nfunction&amp;#39;s .name property should also be set to an appropriate value as it\nis used in default error messages.\nThe modifier function is expected to accept a test function, for example the\narray extension&amp;#39;s test function Array.isArray and return a new modified test.\nThe modifier is expected to provide all arguments it received to the original\ntest function if appropriate, include the this value.\nAs an example, here is the implementation of the not modifier\ntype.modify(&#39;not&#39;, function not(test) {\n    return function() {\n        return !test.apply(this, arguments);\n    };\n});\narrayof\nModifies the test function to return true only if the current value is an array\nof values that all pass the test.\ntype([1, 2, 3]).arrayof.number\ntype({ 0 : 1, 1 : 2, 2 : 3 }).arrayof.number\nassert\nModifies the test function to throw a TypeError if the test fails.\ntype(42).assert.string\ntype(&#39;string&#39;).assert.not.string\ncollapse\nModifies the test function to be called on all values passed to type, returning\nthe first value that passes the test. Returns false otherwise.\ntype(&#39;string&#39;, {}, [], 42, true, Math.PI).collapse.number\ntype(1, function() {}, []).collapse.string\nNote Collapse does not support the alternate calling syntax.\nmaybe\nModifies the test function to return true for null and undefined values.\ntype(null).maybe.number\ntype(12).maybe.number\nnot\nModifies the test function, negating its result.\ntype(&#39;string&#39;).not.number\ntype(Math.PI).not.exists\nof\nSimilar to arrayof but supports all objects.\ntype({ 0 : 1, 1 : 2, 2 : 3 }).arrayof.number\ntype([1, 2, 3]).arrayof.number\nUtil\ntype-mark comes packed with a small utility library for common tasks needed\nelsewhere by the API.\n.util.define(obj : object, name : string, fn : function)\nobject the object to define a property on\nname the name of the property\nfn the function that returns the value of that property\nDefines a readonly property on an object. Used to simplify calling\ndefineProperty.\nobj = {}\ntype.util.define(obj, &#39;x&#39;, function() { return true; })\nobj.x\n.util.toArray(arg : mixed)\narg an array-like object\nreturns an array containing the values of the array-like object\nUsed to convert arguments to an array, or similar objects.\ntype.util.toArray({ 0 : 1, 1 : 2, 2 : 3, length : 3 })\n.util.length(arg : mixed)\narg a value to get the length of\nreturns the length of the value or undefined if not applicable\nReturns a meaningful length value for a given argument. For arrays and strings\nthis means .length. For objects this means the number of key value pairs they\ncontain (excluding Symbols). For all other values undefined is returned.\ntype.util.length([1, 2, 3])\ntype.util.length(&#39;Hello World!&#39;)\ntype.util.length({ x : &#39;x&#39;, y : &#39;y&#39; })\ntype.util.length(12)\n.util.curry(fn : function, [arity : number])\nfn the function to curry\narity an optional argument specifying the arity of the function\nreturns the curried function\nCurries a function so that if it receives less than the functions&amp;#39;s arity in\narguments it returns a new function expecting arity minus the number of\narguments received arguments. The returned function will also behave in this\nway.\nBy default the .length property of the function is used for arity.\nBased off the implementation explained\nhere.\nfn = type.util.curry(function(a, b, c) { return a + b + c; })\nfn(1)(2)(3)\nfn(1, 2)(3)\nfn(1)(2, 3)\nfn(1, 2, 3)\n',
          route: '/api',
          layout: '../layouts/API',
          title: 'TypeMark | API',
      }),
      index: new Page({
          name: 'index',
          content: "# Why Use type-mark\n\nBecause `typeof` just doesn't cut it. The canonical example being\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntypeof null\n```\n\nWith type-mark checking for `null` is as easy as\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(null).object\n```\nNot to mention the added benefits of [modifiers](#modifiers), [interfaces](#interfaces), and\n[custom validation](#writing-your-own-tests).\n\n# Considerations\n\ntype-mark is a **dependency free** library clocking in at ~8.5kB. In\nterms of browser compatibility you will be safe in the following browser\nversions based on [MDN](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).\n\n| Firefox (Gecko) | Chrome | Internet Explorer | Opera | Safari |\n| ------- | --------------- | ------ | ----------------- | ----- | ------ |\n| 4.0 (2) | 5 | 9 | 11.60 | 5.1\n\n# Installing\n\n## On the Client\n\nYou can use the rawgit CDN to get the latest minified version\n\n```lang:html-readonly\n<script type=\"text/javascript\" src=\"{{ site.cdn }}\"></script>\n```\n\nOr you can include your own. Just save a copy of the minified file to your\nsite's javascript directory.\n\n```lang:html-readonly\n<script type=\"text/javascript\" src=\"js/type-mark.min.js\"></script>\n```\n\nUsing any of the above methods will make type-check available via your\nchoice of commonjs interface. If `require` is not defined type-check defines\n`type` on the window.\n\n## On Node\n\ntype-mark is available through [npm](https://www.npmjs.com/). When using\n[node.js](https://nodejs.org/en/) you can install using npm\n\n```readonly-nolines\n$ npm install type-mark\n```\n\nTo use type-mark in your Node project you will need to require it\n```lang:js-readonly\nvar type = require('type-mark');\n```\n\n## From Scratch\n\nYou can also clone the Git repository if you want the full source or are\ninterested in making modifications. type-check is dependency free so working\nwith it is as easy as cloning.\n\n```readonly-nolines\n$ git clone https://github.com/ejrbuss/type-mark.git\n```\n\nTo run the npm scripts you will need to run `npm install` as well as have the\nfollowing global dependencies\n\n- [mocha](https://mochajs.org/),\n- [istanbul](https://istanbul.js.org/),\n- [browserify](http://browserify.org/),\n- [uglify-js](https://www.npmjs.com/package/uglify-js) and\n- [jekyll/bundle](https://jekyllrb.com/).\n\nThe following npm scripts are made available\n\n```readonly-nolines\n$ npm run test     # run tests and code coverage\n$ npm run build    # build type-mark.js and type-mark.min.js for the client\n$ npm run site     # run the docs site\n$ npm run version  # update version number and cdn\n```\n\n# Getting Started\n\nFor most checks the following call pattern is used\n\n```lang:js-readonly\ntype(variable).modifier1.modifier2.check\n```\n\nFor example if you wanted to check if `x` is a string\n\n```lang:js-readonly\ntype(x).string\n```\n\nIf `x` is not a string this will return `false`. If `x` is a string this will\nreturn `true`. The same check can be made by calling the test function directly.\n\n```lang:js-readonly\ntype.string(x)\n```\n\nThe following checks can be made using either syntax.\n\n| Check | Description |\n| ----- | ----------- |\n| `type(x).undefined` | Check if `x` is undefined |\n| `type(x).boolean` | Check if `x` is a boolean |\n| `type(x).number` | Check if `x` is a number |\n| `type(x).integer` | Check if `x` is an integer |\n| `type(x).even` | Check if `x` is even |\n| `type(x).odd` | Check if `x` is odd |\n| `type(x).positive` | Check if `x` is positive |\n| `type(x).negative` | Check if `x` is negative |\n| `type(x).string` | Check if `x` is a string |\n| `type(x).function` | Check if `x` is a function |\n| `type(x).native` | Check if `x` is a native function |\n| `type(x).object` | Check if `x` is an object and not `null` |\n| `type(x).symbol` | Check if `x` is a symbol |\n| `type(x).array` | Check if `x` is an array |\n| `type(x).empty` | Check if `x` is empty[1] |\n| `type(x).exists` | Check if `x` is not `null` or `undefined` |\n\n[1] *Works for `strings`, `arrays`, and `objects` based on keys*\n\nIn addition to basic checks there are also checks that take arguments. An\nexample of this is `instanceof`, which checks to see what constructor\nwas used to create the given object. For example, to check if `x` is a RegExp\n\n```lang:js-readonly\ntype(x).instanceof(RegExp)\n```\n\nTo call the check directly the variable needed to be tested needs to be passed\nin second. So the above check becomes\n\n```lang:js-readonly\ntype.instanceof(RegExp, x);\n```\n\nThe order of arguments here allows all test functions to be\n[curryable](https://en.wikipedia.org/wiki/Currying). This means if you were\nconstantly checking if variables were instances of `YourClass` you could\ninstantly create a checking function like so\n\n```lang:js-readonly\ncheckYourClass = type.instanceof(YourClass);\ncheckYourClass(x);\n```\n\nThis functionality applies to your own tests (see the section\non [extending type-mark](#writing-your-own-tests)). The following checks\ntake arguments just like `instanceof`.\n\n| Check | Description |\n| ----- | ----------- |\n| `type(x).implements(interface)` | Check if `x` implements `interface`, see the section on [interfaces](#interfaces) |\n| `type(x).instanceof(constructor)` | Check if `x` is an instance of `constructor` |\n| `type(x).lengthof(n)` | Check if `x` has a length of `n`[1] |\n| `type(x).max(n)` | Check if `x` is less than or equal to `n` |\n| `type(x).min(n)` | Check if `x` is greater than or equal to `n` |\n| `type(x).range(min, max)` | Check if `x` is greater than or equal to `min` and less than `max` |\n| `type(x).and(...checks)` | Check if all `checks` pass for `x`[2] |\n| `type(x).or(...checks)` | Check if any `checks` pass for `x`[2] |\n\n[1] *Works for `strings`, `arrays`, and `objects` based on keys*\n\n[2] *When curried only accepts two check arguments*\n\n## Modifiers\n\nBy themselves these check functions are still limited and only allow for a\nsurface level checking of primitives. Modifiers are values you can prefix your\ncheck with to modify its effect. Modifiers are applied in a stack, last in first\nout, basis. For example\n\n```lang:js-readonly\ntype(x).arrayof.not.number\n```\n\nchecks that x is an array of non-number elements whereas\n\n\n```lang:js-readonly\ntype(x).not.arrayof.number\n```\n\nchecks that x is not an array of numbers.\n\n### `not`\n\nNegates the given test. For example\n\n```lang:js-readonly\ntype(x).not.string\n```\n\nchecks that `x` is **not** a string. Can also be called\n\n```lang:js-readonly\ntype.not.string(x)\n```\n\n### `assert`\n\nIf the given check fails, a `TypeError` is thrown with a message indicating why\nthe check failed. For example\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(4).assert.string\n```\n\nAsserts that 4 is a string, which fails. Can also be called\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype.assert.string(4)\n```\n\nA custom error message can be specified using the `message` function. `message`\ntakes a function which is called with the value being tested as well as any\narguments supplied to the test and uses the return result as the error message.\n`message` also accepts a string for non-dynamic error messages.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(undefined).message(function(value) {\n    return 'Oops I got ' + value\n}).assert.exists\n```\n\n### `arrayof`\n\nRather than checking the given value this instead checks the elements of the given\nvalue. Automatically fails if the passed value is not an Array. The following\nexample asserts that `x` is an array of numbers.\n\n```lang:js-readonly\ntype(x).arrayof.number\n```\n\nCan also be called\n\n```lang:js-readonly\ntype.arrayof.number(x)\n```\n\n### `of`\n\nRather than checking the passed value, checks the properties of the passed value.\nAutomatically fails if the passed value is not an object. Note\nthat this means `of` works as expected with arrays as well. The following\nexample asserts that `x` is an object whose properties are all strings.\n\n```lang:js-readonly\ntype(x).of.string\n```\n\nCan also be called\n\n```lang:js-readonly\ntype.of.string(x)\n```\n\n### `collapse`\n\nCollapse is useful for functions that take an optional number of out of order\narguments. It returns the first value passed to type that matches the check.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype('string', {}, [], 42, true, Math.PI).collapse.number\n```\n\n**Note** Collapse does not support the alternate calling syntax.\n\n### All Together\n\nModifiers can be combined to create a complex check. For example, here we assert\nthat `x` is not an array of numbers\n\n```lang:js-readonly\ntype(x).assert.not.arrayof.number\n```\n\n## Interfaces\n\nThe checks looked at so far don't do much to help define type checkable objects\nwith a mix of different types. This is where interfaces and type-mark's\nalternate syntax comes in. An interface looks like the following\n\n```lang:js-readonly\nvar myInterface = {\n    name : type.string,\n    age  : type.integer,\n    coordinate : {\n        x : type.number,\n        y : type.number,\n        z : type.number\n    }\n};\n```\n\nInterfaces can be passed to the `implements` check to check if an object meets\na set of structured tests. For instance, based on our interface above we can\ntest to see if a or b implement the interface.\n\n```lang:js-readonly\nvar a = {\n    name : 'bear',\n    age  : 14.5,\n    coordinate : {\n       x : 0.0,\n       y : 1.1, \n       z : 0.1\n    }\n}\nvar b = {\n    name : 'bird',\n    age  : 1,\n    coordinate : {\n        x : 0.0,\n        y : 0.0,\n        z : 14.0,\n        flag : true\n    }\n}\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(a).implements(myInterface)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(b).implements(myInterface)\n```\n\nA couple of things to note about this example. First notice that `a` fails the\ncheck even though only one of its properties is incorrect. `age` is a float rather than an integer. Also `b` succeeds the check even though it contains additional data `coordinates.flag`. The `implements` check does not care if the object it received contains additional properties.\n\nInterfaces may also be nested within interfaces. You can use `type.implements`\nto achieve this. For example\n\n```lang:js-readonly\nvar nestedInterface = {\n    coordinates : type.arrayof.implements({\n        x : type.number,\n        y : type.number\n    })\n};\n```\n\nis a valid interface that checks if the supplied object contains a property\ncoordinates that is an array of `{x, y}` objects. Interfaces are just a composed set of validation functions. Because\n`type.implements(interface)` returns a function it can also be used for validation.\n\nThis also means that you can provide whatever function to the interface you\nwould like, for instance\n\n```lang:js-readonly\nvar interface = {\n    three : function isThree(arg) {\n        return arg === 3 || /^(3|three|iii)$/i.test(arg);\n    }\n};\n```\n\nIs also a valid interface. This makes interfaces extremely flexible especially\nwhen combined with custom tests described in the next section.\n\n## Writing Your Own Tests\n\ntype-mark provides two functions for adding tests: `extend` and `extendfn`. The\nfirst allows you to define simple property-based checks, the second allows for\ncurryable functions.\n\n### `extend`\n\nCreates a new property-based check.\n\n```lang:js-readonly\ntype.extend('nameOfTest', function test(value) {\n    return isValueCorrect(value);\n}, function customMessage(value) {\n    return value + ' was not correct :(';\n});\n```\n\nThe first argument passed to `extend` is the name of the test, which will be\nused for the default error message as well as defining all the access points\nie. `type(x).name`, `type.not.name`, etc.\n\nThe second argument passed to `extend` is the test function itself. It receives\nthe value currently being tested and is expected to return a boolean result.\nIt is also executed in the context of the `TypeState` object it is being\ncalled on (as `this`). This gives you access to information such as the user specified\nmessage, the currently set modifiers, and more. see the\n[API]({{ \"/api\" | relative_url }}) for all the details.\n\nThe third (optional) argument passed to `extend` is the error message function.\nThis will be called if your test was asserted and failed. It is passed the value\nbeing tested and is also executed in the context of the `TypeState` object.\n\nAs an example we will use our previous `isThree` function\n\n```lang:js-readonly\nfunction isThree(arg) {\n    return arg === 3 || /^(3|three|iii)$/i.test(arg);\n}\n```\n\nTo create a new property check we would\n\n```lang:js-readonly\ntype.extend('isThree', isThree, function(arg) {\n    return arg + ' is not three :(';\n});\n```\n\nWe can now use isThree in all the ways you would expect.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(3).isThree\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype('three').not.isThree\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype.arrayof.isThree([3, 'THREE', 'IiI'])\n```\n\n## `extendfn`\n\nCreates a new function-based check. Takes the same arguments as `extend`\nexcept it will be passed any number of specified arguments prior to the actual\nvalue being tested. For example, lets create a validation function that asserts\nthat three numbers sum to 100.\n\n```lang:js-readonly\nfunction threeSumTo100(n1, n2, arg) {\n    return n1 + n2 + arg === 100;\n}\n```\n\nTo create a new function check we would\n\n```lang:js-readonly\ntype.extendfn('threeSumTo100', threeSumTo100, function(n1, n2, arg) {\n    return n1 + ' + ' + n2 + ' + ' + arg + ' does not equal 100';\n});\n```\n\nWe can now use threeSumTo100 in all the ways you would expect.\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype(50).threeSumTo100(25, 25)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype('100').threeSumTo100(0, 0)\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype.arrayof.threeSumTo100(90, 5, [5, 5, 5])\n```\n\n```lang:js-evaluator:jsEvaluator-immediate-readonly\ntype.threeSumTo100(33)(33)(33)\n```\n\nNote that `type.threeSumTo100` is now a curried function. This means we can\npartially apply parameters to create new functions. For example\n\n```lang:js-readonly\nvar twoSumTo50 = type.threeSumTo100(50)\n```\n\n# Try it Out\nYou can type your own type-mark expressions in the editor below. Give it a go!\n```lang:js-evaluator:jsEvaluator-placeholder\nTry writing some code! eg. type(4).numbeer\n```\n\n# Contact\n\nIf you are interested in my other work checkout my [website](http://www.ejrbuss.net)\n\nEmail [ejrbuss@gmail.com](mailto:ejrbuss@gmail.com)\n\n# License\n\ntype-mark is made available under the\n[MIT](https://github.com/ejrbuss/type-mark/blob/master/LICENSE) license.\nThat basically means anything goes! Just don't come crying to me if you\nhurt yourself.",
          plainTxt: 'Why Use type-mark\nBecause typeof just doesn&amp;#39;t cut it. The canonical example being\ntypeof null\nWith type-mark checking for null is as easy as\ntype(null).object\nNot to mention the added benefits of modifiers, interfaces, and\ncustom validation.\nConsiderations\ntype-mark is a dependency free library clocking in at ~8.5kB. In\nterms of browser compatibility you will be safe in the following browser\nversions based on MDN.\n| Firefox (Gecko) | Chrome | Internet Explorer | Opera | Safari |\n| ------- | --------------- | ------ | ----------------- | ----- | ------ |\n| 4.0 (2) | 5 | 9 | 11.60 | 5.1\nInstalling\nOn the Client\nYou can use the rawgit CDN to get the latest minified version\n&lt;script type=&quot;text/javascript&quot; src=&quot;{{ site.cdn }}&quot;&gt;&lt;/script&gt;\nOr you can include your own. Just save a copy of the minified file to your\nsite&amp;#39;s javascript directory.\n&lt;script type=&quot;text/javascript&quot; src=&quot;js/type-mark.min.js&quot;&gt;&lt;/script&gt;\nUsing any of the above methods will make type-check available via your\nchoice of commonjs interface. If require is not defined type-check defines\ntype on the window.\nOn Node\ntype-mark is available through npm. When using\nnode.js you can install using npm\n$ npm install type-mark\nTo use type-mark in your Node project you will need to require it\nvar type = require(&#39;type-mark&#39;);\nFrom Scratch\nYou can also clone the Git repository if you want the full source or are\ninterested in making modifications. type-check is dependency free so working\nwith it is as easy as cloning.\n$ git clone https://github.com/ejrbuss/type-mark.git\nTo run the npm scripts you will need to run npm install as well as have the\nfollowing global dependencies\nmocha,\nistanbul,\nbrowserify,\nuglify-js and\njekyll/bundle.\n\nThe following npm scripts are made available\n$ npm run test     # run tests and code coverage\n$ npm run build    # build type-mark.js and type-mark.min.js for the client\n$ npm run site     # run the docs site\n$ npm run version  # update version number and cdn\nGetting Started\nFor most checks the following call pattern is used\ntype(variable).modifier1.modifier2.check\nFor example if you wanted to check if x is a string\ntype(x).string\nIf x is not a string this will return false. If x is a string this will\nreturn true. The same check can be made by calling the test function directly.\ntype.string(x)\nThe following checks can be made using either syntax.\nCheck\nDescription\n\n\ntype(x).undefined\nCheck if x is undefined\n\ntype(x).boolean\nCheck if x is a boolean\n\ntype(x).number\nCheck if x is a number\n\ntype(x).integer\nCheck if x is an integer\n\ntype(x).even\nCheck if x is even\n\ntype(x).odd\nCheck if x is odd\n\ntype(x).positive\nCheck if x is positive\n\ntype(x).negative\nCheck if x is negative\n\ntype(x).string\nCheck if x is a string\n\ntype(x).function\nCheck if x is a function\n\ntype(x).native\nCheck if x is a native function\n\ntype(x).object\nCheck if x is an object and not null\n\ntype(x).symbol\nCheck if x is a symbol\n\ntype(x).array\nCheck if x is an array\n\ntype(x).empty\nCheck if x is empty[1]\n\ntype(x).exists\nCheck if x is not null or undefined\n\n\n[1] Works for strings, arrays, and objects based on keys\nIn addition to basic checks there are also checks that take arguments. An\nexample of this is instanceof, which checks to see what constructor\nwas used to create the given object. For example, to check if x is a RegExp\ntype(x).instanceof(RegExp)\nTo call the check directly the variable needed to be tested needs to be passed\nin second. So the above check becomes\ntype.instanceof(RegExp, x);\nThe order of arguments here allows all test functions to be\ncurryable. This means if you were\nconstantly checking if variables were instances of YourClass you could\ninstantly create a checking function like so\ncheckYourClass = type.instanceof(YourClass);\ncheckYourClass(x);\nThis functionality applies to your own tests (see the section\non extending type-mark). The following checks\ntake arguments just like instanceof.\nCheck\nDescription\n\n\ntype(x).implements(interface)\nCheck if x implements interface, see the section on interfaces\n\ntype(x).instanceof(constructor)\nCheck if x is an instance of constructor\n\ntype(x).lengthof(n)\nCheck if x has a length of n[1]\n\ntype(x).max(n)\nCheck if x is less than or equal to n\n\ntype(x).min(n)\nCheck if x is greater than or equal to n\n\ntype(x).range(min, max)\nCheck if x is greater than or equal to min and less than max\n\ntype(x).and(...checks)\nCheck if all checks pass for x[2]\n\ntype(x).or(...checks)\nCheck if any checks pass for x[2]\n\n\n[1] Works for strings, arrays, and objects based on keys\n[2] When curried only accepts two check arguments\nModifiers\nBy themselves these check functions are still limited and only allow for a\nsurface level checking of primitives. Modifiers are values you can prefix your\ncheck with to modify its effect. Modifiers are applied in a stack, last in first\nout, basis. For example\ntype(x).arrayof.not.number\nchecks that x is an array of non-number elements whereas\ntype(x).not.arrayof.number\nchecks that x is not an array of numbers.\nnot\nNegates the given test. For example\ntype(x).not.string\nchecks that x is not a string. Can also be called\ntype.not.string(x)\nassert\nIf the given check fails, a TypeError is thrown with a message indicating why\nthe check failed. For example\ntype(4).assert.string\nAsserts that 4 is a string, which fails. Can also be called\ntype.assert.string(4)\nA custom error message can be specified using the message function. message\ntakes a function which is called with the value being tested as well as any\narguments supplied to the test and uses the return result as the error message.\nmessage also accepts a string for non-dynamic error messages.\ntype(undefined).message(function(value) {\n    return &#39;Oops I got &#39; + value\n}).assert.exists\narrayof\nRather than checking the given value this instead checks the elements of the given\nvalue. Automatically fails if the passed value is not an Array. The following\nexample asserts that x is an array of numbers.\ntype(x).arrayof.number\nCan also be called\ntype.arrayof.number(x)\nof\nRather than checking the passed value, checks the properties of the passed value.\nAutomatically fails if the passed value is not an object. Note\nthat this means of works as expected with arrays as well. The following\nexample asserts that x is an object whose properties are all strings.\ntype(x).of.string\nCan also be called\ntype.of.string(x)\ncollapse\nCollapse is useful for functions that take an optional number of out of order\narguments. It returns the first value passed to type that matches the check.\ntype(&#39;string&#39;, {}, [], 42, true, Math.PI).collapse.number\nNote Collapse does not support the alternate calling syntax.\nAll Together\nModifiers can be combined to create a complex check. For example, here we assert\nthat x is not an array of numbers\ntype(x).assert.not.arrayof.number\nInterfaces\nThe checks looked at so far don&amp;#39;t do much to help define type checkable objects\nwith a mix of different types. This is where interfaces and type-mark&amp;#39;s\nalternate syntax comes in. An interface looks like the following\nvar myInterface = {\n    name : type.string,\n    age  : type.integer,\n    coordinate : {\n        x : type.number,\n        y : type.number,\n        z : type.number\n    }\n};\nInterfaces can be passed to the implements check to check if an object meets\na set of structured tests. For instance, based on our interface above we can\ntest to see if a or b implement the interface.\nvar a = {\n    name : &#39;bear&#39;,\n    age  : 14.5,\n    coordinate : {\n       x : 0.0,\n       y : 1.1, \n       z : 0.1\n    }\n}\nvar b = {\n    name : &#39;bird&#39;,\n    age  : 1,\n    coordinate : {\n        x : 0.0,\n        y : 0.0,\n        z : 14.0,\n        flag : true\n    }\n}\ntype(a).implements(myInterface)\ntype(b).implements(myInterface)\nA couple of things to note about this example. First notice that a fails the\ncheck even though only one of its properties is incorrect. age is a float rather than an integer. Also b succeeds the check even though it contains additional data coordinates.flag. The implements check does not care if the object it received contains additional properties.\nInterfaces may also be nested within interfaces. You can use type.implements\nto achieve this. For example\nvar nestedInterface = {\n    coordinates : type.arrayof.implements({\n        x : type.number,\n        y : type.number\n    })\n};\nis a valid interface that checks if the supplied object contains a property\ncoordinates that is an array of {x, y} objects. Interfaces are just a composed set of validation functions. Because\ntype.implements(interface) returns a function it can also be used for validation.\nThis also means that you can provide whatever function to the interface you\nwould like, for instance\nvar interface = {\n    three : function isThree(arg) {\n        return arg === 3 || /^(3|three|iii)$/i.test(arg);\n    }\n};\nIs also a valid interface. This makes interfaces extremely flexible especially\nwhen combined with custom tests described in the next section.\nWriting Your Own Tests\ntype-mark provides two functions for adding tests: extend and extendfn. The\nfirst allows you to define simple property-based checks, the second allows for\ncurryable functions.\nextend\nCreates a new property-based check.\ntype.extend(&#39;nameOfTest&#39;, function test(value) {\n    return isValueCorrect(value);\n}, function customMessage(value) {\n    return value + &#39; was not correct :(&#39;;\n});\nThe first argument passed to extend is the name of the test, which will be\nused for the default error message as well as defining all the access points\nie. type(x).name, type.not.name, etc.\nThe second argument passed to extend is the test function itself. It receives\nthe value currently being tested and is expected to return a boolean result.\nIt is also executed in the context of the TypeState object it is being\ncalled on (as this). This gives you access to information such as the user specified\nmessage, the currently set modifiers, and more. see the\n[API]({{ &amp;quot;/api&amp;quot; | relative_url }}) for all the details.\nThe third (optional) argument passed to extend is the error message function.\nThis will be called if your test was asserted and failed. It is passed the value\nbeing tested and is also executed in the context of the TypeState object.\nAs an example we will use our previous isThree function\nfunction isThree(arg) {\n    return arg === 3 || /^(3|three|iii)$/i.test(arg);\n}\nTo create a new property check we would\ntype.extend(&#39;isThree&#39;, isThree, function(arg) {\n    return arg + &#39; is not three :(&#39;;\n});\nWe can now use isThree in all the ways you would expect.\ntype(3).isThree\ntype(&#39;three&#39;).not.isThree\ntype.arrayof.isThree([3, &#39;THREE&#39;, &#39;IiI&#39;])\nextendfn\nCreates a new function-based check. Takes the same arguments as extend\nexcept it will be passed any number of specified arguments prior to the actual\nvalue being tested. For example, lets create a validation function that asserts\nthat three numbers sum to 100.\nfunction threeSumTo100(n1, n2, arg) {\n    return n1 + n2 + arg === 100;\n}\nTo create a new function check we would\ntype.extendfn(&#39;threeSumTo100&#39;, threeSumTo100, function(n1, n2, arg) {\n    return n1 + &#39; + &#39; + n2 + &#39; + &#39; + arg + &#39; does not equal 100&#39;;\n});\nWe can now use threeSumTo100 in all the ways you would expect.\ntype(50).threeSumTo100(25, 25)\ntype(&#39;100&#39;).threeSumTo100(0, 0)\ntype.arrayof.threeSumTo100(90, 5, [5, 5, 5])\ntype.threeSumTo100(33)(33)(33)\nNote that type.threeSumTo100 is now a curried function. This means we can\npartially apply parameters to create new functions. For example\nvar twoSumTo50 = type.threeSumTo100(50)\nTry it Out\nYou can type your own type-mark expressions in the editor below. Give it a go!\nTry writing some code! eg. type(4).numbeer\nContact\nIf you are interested in my other work checkout my website\nEmail ejrbuss@gmail.com\nLicense\ntype-mark is made available under the\nMIT license.\nThat basically means anything goes! Just don&amp;#39;t come crying to me if you\nhurt yourself.\n',
          route: '/index',
          layout: '../layouts/Docs',
          title: 'TypeMark',
          subtitle: 'make type checking *lovely*',
          version: 'v2.0.0',
      }),
  
  };
  