You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

README.md 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. [![*nix build status][nix-build-image]][nix-build-url]
  2. [![Windows build status][win-build-image]][win-build-url]
  3. [![Tests coverage][cov-image]][cov-url]
  4. [![npm version][npm-image]][npm-url]
  5. # type
  6. ## Runtime validation and processing of JavaScript types
  7. - Respects language nature and acknowledges its quirks
  8. - Allows coercion in restricted forms (rejects clearly invalid input, normalizes permissible type deviations)
  9. - No transpilation implied, written to work in all ECMAScript 3+ engines
  10. ### Example usage
  11. Bulletproof input arguments normalization and validation:
  12. ```javascript
  13. const ensureString = require('type/string/ensure')
  14. , ensureDate = require('type/date/ensure')
  15. , ensureNaturalNumber = require('type/natural-number/ensure')
  16. , isObject = require('type/object/is');
  17. module.exports = (path, options = { min: 0 }) {
  18. path = ensureString(path, { errorMessage: "%v is not a path" });
  19. if (!isObject(options)) options = {};
  20. const min = ensureNaturalNumber(options.min, { default: 0 })
  21. , max = ensureNaturalNumber(options.max, { isOptional: true })
  22. , startTime = ensureDate(options.startTime, { isOptional: true });
  23. // ...logic
  24. };
  25. ```
  26. ### Installation
  27. ```bash
  28. npm install type
  29. ```
  30. ## Utilities
  31. Serves following kind of utilities:
  32. ##### `*/coerce`
  33. Restricted coercion into primitive type. Returns coerced value or `null` if value is not coercible per rules.
  34. ##### `*/is`
  35. Object type/kind confirmation, returns either `true` or `false`.
  36. ##### `*/ensure`
  37. Value validation. Returns input value (in primitive cases possibly coerced) or if value doesn't meet the constraints throws `TypeError` .
  38. Each `*/ensure` utility, accepts following options (eventually passed with second argument):
  39. - `isOptional` - Makes `null` or `undefined` accepted as valid value. In such case instead of `TypeError` being thrown, `null` is returned.
  40. - `default` - A value to be returned if `null` or `undefined` is passed as an input value.
  41. - `errorMessage` - Custom error message (`%v` can be used as a placeholder for input value)
  42. ---
  43. ### Value
  44. _Value_, any value that's neither `null` nor `undefined` .
  45. #### `value/is`
  46. Confirms whether passed argument is a _value_
  47. ```javascript
  48. const isValue = require("type/value/is");
  49. isValue({}); // true
  50. isValue(null); // false
  51. ```
  52. #### `value/ensure`
  53. Ensures if given argument is a _value_. If it's a value it is returned back, if not `TypeError` is thrown
  54. ```javascript
  55. const ensureValue = require("type/value/ensure");
  56. const obj = {};
  57. ensureValue(obj); // obj
  58. ensureValue(null); // Thrown TypeError: Cannot use null
  59. ```
  60. ---
  61. ### Object
  62. _Object_, any non-primitive value
  63. #### `object/is`
  64. Confirms if passed value is an object
  65. ```javascript
  66. const isObject = require("type/object/is");
  67. isObject({}); // true
  68. isObject(true); // false
  69. isObject(null); // false
  70. ```
  71. #### `object/ensure`
  72. If given argument is an object, it is returned back. Otherwise `TypeError` is thrown.
  73. ```javascript
  74. const ensureObject = require("type/object/ensure");
  75. const obj = {};
  76. ensureObject(obj); // obj
  77. ensureString(null); // Thrown TypeError: null is not an object
  78. ```
  79. ---
  80. ### String
  81. _string_ primitive
  82. #### `string/coerce`
  83. Restricted string coercion. Returns string presentation for every value that follows below constraints
  84. - is implicitly coercible to string
  85. - is neither`null` nor `undefined`
  86. - its `toString` method is not `Object.prototype.toString`
  87. For all other values `null` is returned
  88. ```javascript
  89. const coerceToString = require("type/string/coerce");
  90. coerceToString(12); // "12"
  91. coerceToString(undefined); // null
  92. ```
  93. #### `string/ensure`
  94. If given argument is a string coercible value (via [`string/coerce`](#stringcoerce)) returns result string.
  95. Otherwise `TypeError` is thrown.
  96. ```javascript
  97. const ensureString = require("type/string/ensure");
  98. ensureString(12); // "12"
  99. ensureString(null); // Thrown TypeError: null is not a string
  100. ```
  101. ---
  102. ### Number
  103. _number_ primitive
  104. #### `number/coerce`
  105. Restricted number coercion. Returns number presentation for every value that follows below constraints
  106. - is implicitly coercible to number
  107. - is neither `null` nor `undefined`
  108. - is not `NaN` and doesn't coerce to `NaN`
  109. For all other values `null` is returned
  110. ```javascript
  111. const coerceToNumber = require("type/number/coerce");
  112. coerceToNumber("12"); // 12
  113. coerceToNumber({}); // null
  114. coerceToNumber(null); // null
  115. ```
  116. #### `number/ensure`
  117. If given argument is a number coercible value (via [`number/coerce`](#numbercoerce)) returns result number.
  118. Otherwise `TypeError` is thrown.
  119. ```javascript
  120. const ensureNumber = require("type/number/ensure");
  121. ensureNumber(12); // "12"
  122. ensureNumber(null); // Thrown TypeError: null is not a number
  123. ```
  124. ---
  125. #### Finite Number
  126. Finite _number_ primitive
  127. ##### `finite/coerce`
  128. Follows [`number/coerce`](#numbercoerce) additionally rejecting `Infinity` and `-Infinity` values (`null` is returned if given values coerces to them)
  129. ```javascript
  130. const coerceToFinite = require("type/finite/coerce");
  131. coerceToFinite("12"); // 12
  132. coerceToFinite(Infinity); // null
  133. coerceToFinite(null); // null
  134. ```
  135. ##### `finite/ensure`
  136. If given argument is a finite number coercible value (via [`finite/coerce`](#finitecoerce)) returns result number.
  137. Otherwise `TypeError` is thrown.
  138. ```javascript
  139. const ensureFinite = require("type/finite/ensure");
  140. ensureFinite(12); // "12"
  141. ensureFinite(null); // Thrown TypeError: null is not a finite number
  142. ```
  143. ---
  144. #### Integer Number
  145. Integer _number_ primitive
  146. ##### `integer/coerce`
  147. Follows [`finite/coerce`](#finitecoerce) additionally stripping decimal part from the number
  148. ```javascript
  149. const coerceToInteger = require("type/integer/coerce");
  150. coerceToInteger("12.95"); // 12
  151. coerceToInteger(Infinity); // null
  152. coerceToInteger(null); // null
  153. ```
  154. ##### `integer/ensure`
  155. If given argument is an integer coercible value (via [`integer/coerce`](#integercoerce)) returns result number.
  156. Otherwise `TypeError` is thrown.
  157. ```javascript
  158. const ensureInteger = require("type/integer/ensure");
  159. ensureInteger(12.93); // "12"
  160. ensureInteger(null); // Thrown TypeError: null is not an integer
  161. ```
  162. ---
  163. #### Safe Integer Number
  164. Safe integer _number_ primitive
  165. ##### `safe-integer/coerce`
  166. Follows [`integer/coerce`](#integercoerce) but returns `null` in place of values which are beyond `Number.MIN_SAFE_INTEGER` and `Number.MAX_SAFE_INTEGER` range.
  167. ```javascript
  168. const coerceToSafeInteger = require("type/safe-integer/coerce");
  169. coerceToInteger("12.95"); // 12
  170. coerceToInteger(9007199254740992); // null
  171. coerceToInteger(null); // null
  172. ```
  173. ##### `safe-integer/ensure`
  174. If given argument is a safe integer coercible value (via [`safe-integer/coerce`](#safe-integercoerce)) returns result number.
  175. Otherwise `TypeError` is thrown.
  176. ```javascript
  177. const ensureSafeInteger = require("type/safe-integer/ensure");
  178. ensureSafeInteger(12.93); // "12"
  179. ensureSafeInteger(9007199254740992); // Thrown TypeError: null is not a safe integer
  180. ```
  181. ---
  182. #### Natural Number
  183. Natural _number_ primitive
  184. ##### `natural-number/coerce`
  185. Follows [`integer/coerce`](#integercoerce) but returns `null` for values below `0`
  186. ```javascript
  187. const coerceToNaturalNumber = require("type/natural-number/coerce");
  188. coerceToNaturalNumber("12.95"); // 12
  189. coerceToNaturalNumber(-120); // null
  190. coerceToNaturalNumber(null); // null
  191. ```
  192. ##### `natural-number/ensure`
  193. If given argument is a natural number coercible value (via [`natural-number/coerce`](#natural-numbercoerce)) returns result number.
  194. Otherwise `TypeError` is thrown.
  195. ```javascript
  196. const ensureNaturalNumber = require("type/natural-number/ensure");
  197. ensureNaturalNumber(12.93); // "12"
  198. ensureNaturalNumber(-230); // Thrown TypeError: null is not a natural number
  199. ```
  200. ---
  201. ### Plain Object
  202. A _plain object_
  203. - Inherits directly from `Object.prototype` or `null`
  204. - Is not a constructor's `prototype` property
  205. #### `plain-object/is`
  206. Confirms if given object is a _plain object_
  207. ```javascript
  208. const isPlainObject = require("type/plain-object/is");
  209. isPlainObject({}); // true
  210. isPlainObject(Object.create(null)); // true
  211. isPlainObject([]); // false
  212. ```
  213. #### `plain-object/ensure`
  214. If given argument is a plain object it is returned back. Otherwise `TypeError` is thrown.
  215. ```javascript
  216. const ensurePlainObject = require("type/plain-object/ensure");
  217. ensurePlainObject({}); // {}
  218. ensureArray("foo"); // Thrown TypeError: foo is not a plain object
  219. ```
  220. ---
  221. ### Array
  222. _Array_ instance
  223. #### `array/is`
  224. Confirms if given object is a native array
  225. ```javascript
  226. const isArray = require("type/array/is");
  227. isArray([]); // true
  228. isArray({}); // false
  229. isArray("foo"); // false
  230. ```
  231. #### `array/ensure`
  232. If given argument is an array, it is returned back. Otherwise `TypeError` is thrown.
  233. ```javascript
  234. const ensureArray = require("type/array/ensure");
  235. ensureArray(["foo"]); // ["foo"]
  236. ensureArray("foo"); // Thrown TypeError: foo is not an array
  237. ```
  238. ---
  239. #### Array Like
  240. _Array-like_ value (any value with `length` property)
  241. #### `array-like/is`
  242. Restricted _array-like_ confirmation. Returns true for every value that meets following contraints
  243. - is an _object_ (or with `allowString` option, a _string_)
  244. - is not a _function_
  245. - Exposes `length` that meets [`array-length`](#array-lengthcoerce) constraints
  246. ```javascript
  247. const isArrayLike = require("type/array-like/is");
  248. isArrayLike([]); // true
  249. isArrayLike({}); // false
  250. isArrayLike({ length: 0 }); // true
  251. isArrayLike("foo"); // false
  252. isArrayLike("foo", { allowString: true }); // true
  253. ```
  254. #### `array-like/ensure`
  255. If given argument is an _array-like_, it is returned back. Otherwise `TypeError` is thrown.
  256. ```javascript
  257. const ensureArrayLike = require("type/array-like/ensure");
  258. ensureArrayLike({ length: 0 }); // { length: 0 }
  259. ensureArrayLike("foo", { allowString: true }); // "foo"
  260. ensureArrayLike({}); // Thrown TypeError: null is not an iterable
  261. ```
  262. ---
  263. #### Array length
  264. _number_ primitive that conforms as valid _array length_
  265. ##### `array-length/coerce`
  266. Follows [`safe-integer/coerce`](#safe-integercoerce) but returns `null` in place of values which are below `0`
  267. ```javascript
  268. const coerceToArrayLength = require("type/safe-integer/coerce");
  269. coerceToArrayLength("12.95"); // 12
  270. coerceToArrayLength(9007199254740992); // null
  271. coerceToArrayLength(null); // null
  272. ```
  273. ##### `array-length/ensure`
  274. If given argument is an _array length_ coercible value (via [`array-length/coerce`](#array-lengthcoerce)) returns result number.
  275. Otherwise `TypeError` is thrown.
  276. ```javascript
  277. const ensureArrayLength = require("type/array-length/ensure");
  278. ensureArrayLength(12.93); // "12"
  279. ensureArrayLength(9007199254740992); // Thrown TypeError: null is not a valid array length
  280. ```
  281. ---
  282. ### Iterable
  283. Value which implements _iterable_ protocol
  284. #### `iterable/is`
  285. Confirms if given object is an _iterable_ and is not a _string_ (unless `allowString` option is passed)
  286. ```javascript
  287. const isIterable = require("type/iterable/is");
  288. isIterable([]); // true
  289. isIterable({}); // false
  290. isIterable("foo"); // false
  291. isIterable("foo", { allowString: true }); // true
  292. ```
  293. Supports also `denyEmpty` option
  294. ```javascript
  295. isIterable([], { denyEmpty: true }); // false
  296. isIterable(["foo"], { denyEmpty: true }); // true
  297. ```
  298. #### `iterable/ensure`
  299. If given argument is an _iterable_, it is returned back. Otherwise `TypeError` is thrown.
  300. ```javascript
  301. const ensureIterable = require("type/iterable/ensure");
  302. ensureIterable([]); // []
  303. ensureIterable("foo", { allowString: true }); // "foo"
  304. ensureIterable({}); // Thrown TypeError: null is not expected iterable
  305. ```
  306. Additionally items can be coreced with `coerceItem` option. Note that in this case:
  307. - A newly created array with coerced values is returned
  308. - Validation crashes if any of the items is not coercible
  309. ```javascript
  310. ensureIterable(new Set(["foo", 12])); // ["foo", "12"]
  311. ensureIterable(new Set(["foo", {}])); // Thrown TypeError: Set({ "foo", {} }) is not expected iterable
  312. ```
  313. ---
  314. ### Date
  315. _Date_ instance
  316. #### `date/is`
  317. Confirms if given object is a native date, and is not an _Invalid Date_
  318. ```javascript
  319. const isDate = require("type/date/is");
  320. isDate(new Date()); // true
  321. isDate(new Date("Invalid date")); // false
  322. isDate(Date.now()); // false
  323. isDate("foo"); // false
  324. ```
  325. #### `date/ensure`
  326. If given argument is a date object, it is returned back. Otherwise `TypeError` is thrown.
  327. ```javascript
  328. const ensureDate = require("type/date/ensure");
  329. const date = new Date();
  330. ensureDate(date); // date
  331. ensureDate(123123); // Thrown TypeError: 123123 is not a date object
  332. ```
  333. ---
  334. ### Time value
  335. _number_ primitive which is a valid _time value_ (as used internally in _Date_ instances)
  336. #### `time-value/coerce`
  337. Follows [`integer/coerce`](#integercoerce) but returns `null` in place of values which go beyond 100 000 0000 days from unix epoch
  338. ```javascript
  339. const coerceToTimeValue = require("type/time-value/coerce");
  340. coerceToTimeValue(12312312); // true
  341. coerceToTimeValue(Number.MAX_SAFE_INTEGER); // false
  342. coerceToTimeValue("foo"); // false
  343. ```
  344. ##### `time-value/ensure`
  345. If given argument is a _time value_ coercible value (via [`time-value/coerce`](#time-valuecoerce)) returns result number.
  346. Otherwise `TypeError` is thrown.
  347. ```javascript
  348. const ensureTimeValue = require("type/time-value/ensure");
  349. ensureTimeValue(12.93); // "12"
  350. ensureTimeValue(Number.MAX_SAFE_INTEGER); // Thrown TypeError: null is not a natural number
  351. ```
  352. ---
  353. ### Function
  354. _Function_ instance
  355. #### `function/is`
  356. Confirms if given object is a native function
  357. ```javascript
  358. const isFunction = require("type/function/is");
  359. isFunction(function () {}); // true
  360. isFunction(() => {}); // true
  361. isFunction(class {}); // true
  362. isFunction("foo"); // false
  363. ```
  364. #### `function/ensure`
  365. If given argument is a function object, it is returned back. Otherwise `TypeError` is thrown.
  366. ```javascript
  367. const ensureFunction = require("type/function/ensure");
  368. const fn = function () {};
  369. ensureFunction(fn); // fn
  370. ensureFunction(/foo/); // Thrown TypeError: /foo/ is not a function
  371. ```
  372. ---
  373. #### Plain Function
  374. A _Function_ instance that is not a _Class_
  375. ##### `plain-function/is`
  376. Confirms if given object is a _plain function_
  377. ```javascript
  378. const isPlainFunction = require("type/plain-function/is");
  379. isPlainFunction(function () {}); // true
  380. isPlainFunction(() => {}); // true
  381. isPlainFunction(class {}); // false
  382. isPlainFunction("foo"); // false
  383. ```
  384. ##### `plain-function/ensure`
  385. If given argument is a _plain function_ object, it is returned back. Otherwise `TypeError` is thrown.
  386. ```javascript
  387. const ensurePlainFunction = require("type/function/ensure");
  388. const fn = function () {};
  389. ensurePlainFunction(fn); // fn
  390. ensurePlainFunction(class {}); // Thrown TypeError: class is not a plain function
  391. ```
  392. ---
  393. ### RegExp
  394. _RegExp_ instance
  395. #### `reg-exp/is`
  396. Confirms if given object is a native regular expression object
  397. ```javascript
  398. const isRegExp = require("type/reg-exp/is");
  399. isRegExp(/foo/);
  400. isRegExp({}); // false
  401. isRegExp("foo"); // false
  402. ```
  403. #### `reg-exp/ensure`
  404. If given argument is a regular expression object, it is returned back. Otherwise `TypeError` is thrown.
  405. ```javascript
  406. const ensureRegExp = require("type/reg-exp/ensure");
  407. ensureRegExp(/foo/); // /foo/
  408. ensureRegExp("foo"); // Thrown TypeError: null is not a regular expression object
  409. ```
  410. ---
  411. ### Promise
  412. _Promise_ instance
  413. #### `promise/is`
  414. Confirms if given object is a native _promise_
  415. ```javascript
  416. const isPromise = require("type/promise/is");
  417. isPromise(Promise.resolve()); // true
  418. isPromise({ then: () => {} }); // false
  419. isPromise({}); // false
  420. ```
  421. ##### `promise/ensure`
  422. If given argument is a promise, it is returned back. Otherwise `TypeError` is thrown.
  423. ```javascript
  424. const ensurePromise = require("type/promise/ensure");
  425. const promise = Promise.resolve();
  426. ensurePromise(promise); // promise
  427. eensurePromise({}); // Thrown TypeError: [object Object] is not a promise
  428. ```
  429. ---
  430. #### Thenable
  431. _Thenable_ object (an object with `then` method)
  432. ##### `thenable/is`
  433. Confirms if given object is a _thenable_
  434. ```javascript
  435. const isThenable = require("type/thenable/is");
  436. isThenable(Promise.resolve()); // true
  437. isThenable({ then: () => {} }); // true
  438. isThenable({}); // false
  439. ```
  440. ##### `thenable/ensure`
  441. If given argument is a _thenable_ object, it is returned back. Otherwise `TypeError` is thrown.
  442. ```javascript
  443. const ensureThenable = require("type/thenable/ensure");
  444. const promise = Promise.resolve();
  445. ensureThenable(promise); // promise
  446. ensureThenable({}); // Thrown TypeError: [object Object] is not a thenable object
  447. ```
  448. ---
  449. ### Error
  450. _Error_ instance
  451. #### `error/is`
  452. Confirms if given object is a native error object
  453. ```javascript
  454. const isError = require("type/error/is");
  455. isError(new Error()); // true
  456. isError({ message: "Fake error" }); // false
  457. ```
  458. #### `error/ensure`
  459. If given argument is an error object, it is returned back. Otherwise `TypeError` is thrown.
  460. ```javascript
  461. const ensureError = require("type/error/ensure");
  462. const someError = new Error("Some error");
  463. ensureError(someError); // someError
  464. ensureError({ message: "Fake error" }); // Thrown TypeError: [object Object] is not an error object
  465. ```
  466. ---
  467. ### Prototype
  468. Some constructor's `prototype` property
  469. #### `prototype/is`
  470. Confirms if given object serves as a _prototype_ property
  471. ```javascript
  472. const isPrototype = require("type/prototype/is");
  473. isPrototype({}); // false
  474. isPrototype(Object.prototype); // true
  475. isPrototype(Array.prototype); // true
  476. ```
  477. ### Tests
  478. $ npm test
  479. [nix-build-image]: https://semaphoreci.com/api/v1/medikoo-org/type/branches/master/shields_badge.svg
  480. [nix-build-url]: https://semaphoreci.com/medikoo-org/type
  481. [win-build-image]: https://ci.appveyor.com/api/projects/status/8nrtluuwsb5k9l8d?svg=true
  482. [win-build-url]: https://ci.appveyor.com/api/project/medikoo/type
  483. [cov-image]: https://img.shields.io/codecov/c/github/medikoo/type.svg
  484. [cov-url]: https://codecov.io/gh/medikoo/type
  485. [npm-image]: https://img.shields.io/npm/v/type.svg
  486. [npm-url]: https://www.npmjs.com/package/type