Repository: gcanti/io-ts-types (ts)

Issue:
Refactor IntegerFromString using the brand combinator (io-ts@1.8.0)

Pull request:
deprecate IntegerFromString in favour of IntFromString, closes #80

Patch:
diff --git a/docs/modules/IntFromString.ts.md b/docs/modules/IntFromString.ts.md
new file mode 100644
index 0000000..23c39cc
--- /dev/null
+++ b/docs/modules/IntFromString.ts.md
@@ -0,0 +1,36 @@
+---
+title: IntFromString.ts
+nav_order: 16
+parent: Modules
+---
+
+---
+
+<h2 class="text-delta">Table of contents</h2>
+
+- [IntFromString (constant)](#intfromstring-constant)
+
+---
+
+# IntFromString (constant)
+
+A codec that succeeds if a string can be parsed to an integer
+
+**Signature**
+
+```ts
+export const IntFromString: t.Type<t.Int, string, unknown> = ...
+```
+
+**Example**
+
+```ts
+import { IntFromString } from 'io-ts-types/lib/IntFromString'
+import { right } from 'fp-ts/lib/Either'
+import { PathReporter } from 'io-ts/lib/PathReporter'
+
+assert.deepStrictEqual(IntFromString.decode('1'), right(1))
+assert.deepStrictEqual(PathReporter.report(IntFromString.decode('1.1')), [
+  'Invalid value "1.1" supplied to : IntFromString'
+])
+```
diff --git a/docs/modules/JSON/JSONFromString.ts.md b/docs/modules/JSON/JSONFromString.ts.md
index 7116769..6a8cf1b 100644
--- a/docs/modules/JSON/JSONFromString.ts.md
+++ b/docs/modules/JSON/JSONFromString.ts.md
@@ -1,6 +1,6 @@
 ---
 title: JSON/JSONFromString.ts
-nav_order: 16
+nav_order: 17
 parent: Modules
 ---
 
diff --git a/docs/modules/JSON/JSONTypeRT.ts.md b/docs/modules/JSON/JSONTypeRT.ts.md
index 6e1f120..3f63717 100644
--- a/docs/modules/JSON/JSONTypeRT.ts.md
+++ b/docs/modules/JSON/JSONTypeRT.ts.md
@@ -1,6 +1,6 @@
 ---
 title: JSON/JSONTypeRT.ts
-nav_order: 17
+nav_order: 18
 parent: Modules
 ---
 
diff --git a/docs/modules/mapOutput.ts.md b/docs/modules/mapOutput.ts.md
index 78b120c..c84dcbe 100644
--- a/docs/modules/mapOutput.ts.md
+++ b/docs/modules/mapOutput.ts.md
@@ -1,6 +1,6 @@
 ---
 title: mapOutput.ts
-nav_order: 18
+nav_order: 19
 parent: Modules
 ---
 
diff --git a/docs/modules/monocle-ts/TypePrismIso.ts.md b/docs/modules/monocle-ts/TypePrismIso.ts.md
index ebe2027..a84c430 100644
--- a/docs/modules/monocle-ts/TypePrismIso.ts.md
+++ b/docs/modules/monocle-ts/TypePrismIso.ts.md
@@ -1,6 +1,6 @@
 ---
 title: monocle-ts/TypePrismIso.ts
-nav_order: 21
+nav_order: 22
 parent: Modules
 ---
 
diff --git a/docs/modules/monocle-ts/lensesFromInterface.ts.md b/docs/modules/monocle-ts/lensesFromInterface.ts.md
index 5649b84..37793b8 100644
--- a/docs/modules/monocle-ts/lensesFromInterface.ts.md
+++ b/docs/modules/monocle-ts/lensesFromInterface.ts.md
@@ -1,6 +1,6 @@
 ---
 title: monocle-ts/lensesFromInterface.ts
-nav_order: 19
+nav_order: 20
 parent: Modules
 ---
 
diff --git a/docs/modules/monocle-ts/lensesFromProps.ts.md b/docs/modules/monocle-ts/lensesFromProps.ts.md
index 556a2ab..26240b4 100644
--- a/docs/modules/monocle-ts/lensesFromProps.ts.md
+++ b/docs/modules/monocle-ts/lensesFromProps.ts.md
@@ -1,6 +1,6 @@
 ---
 title: monocle-ts/lensesFromProps.ts
-nav_order: 20
+nav_order: 21
 parent: Modules
 ---
 
diff --git a/docs/modules/newtype-ts/fromNewtype.ts.md b/docs/modules/newtype-ts/fromNewtype.ts.md
index 5ed74a4..6f57bdb 100644
--- a/docs/modules/newtype-ts/fromNewtype.ts.md
+++ b/docs/modules/newtype-ts/fromNewtype.ts.md
@@ -1,6 +1,6 @@
 ---
 title: newtype-ts/fromNewtype.ts
-nav_order: 22
+nav_order: 23
 parent: Modules
 ---
 
diff --git a/docs/modules/newtype-ts/fromRefinement.ts.md b/docs/modules/newtype-ts/fromRefinement.ts.md
index 422b3d4..a2b5e9f 100644
--- a/docs/modules/newtype-ts/fromRefinement.ts.md
+++ b/docs/modules/newtype-ts/fromRefinement.ts.md
@@ -1,6 +1,6 @@
 ---
 title: newtype-ts/fromRefinement.ts
-nav_order: 23
+nav_order: 24
 parent: Modules
 ---
 
diff --git a/docs/modules/number/IntegerFromString.ts.md b/docs/modules/number/IntegerFromString.ts.md
index e82ec13..f1812d1 100644
--- a/docs/modules/number/IntegerFromString.ts.md
+++ b/docs/modules/number/IntegerFromString.ts.md
@@ -1,6 +1,6 @@
 ---
 title: number/IntegerFromString.ts
-nav_order: 24
+nav_order: 25
 parent: Modules
 ---
 
@@ -9,7 +9,7 @@ parent: Modules
 <h2 class="text-delta">Table of contents</h2>
 
 - [IntegerFromStringC (interface)](#integerfromstringc-interface)
-- [IntegerFromString (constant)](#integerfromstring-constant)
+- [~~IntegerFromString~~ (constant)](#integerfromstring-constant)
 
 ---
 
@@ -21,7 +21,9 @@ parent: Modules
 export interface IntegerFromStringC extends t.RefinementType<NumberFromStringType, number, string, unknown> {}
 ```
 
-# IntegerFromString (constant)
+# ~~IntegerFromString~~ (constant)
+
+Use `io-ts-types/lib/IntFromString` instead.
 
 **Signature**
 
diff --git a/docs/modules/number/NumberFromString.ts.md b/docs/modules/number/NumberFromString.ts.md
index dabfd9c..2b458ef 100644
--- a/docs/modules/number/NumberFromString.ts.md
+++ b/docs/modules/number/NumberFromString.ts.md
@@ -1,6 +1,6 @@
 ---
 title: number/NumberFromString.ts
-nav_order: 25
+nav_order: 26
 parent: Modules
 ---
 
diff --git a/docs/modules/string/uuid.ts.md b/docs/modules/string/uuid.ts.md
index af002bd..dcccdf0 100644
--- a/docs/modules/string/uuid.ts.md
+++ b/docs/modules/string/uuid.ts.md
@@ -1,6 +1,6 @@
 ---
 title: string/uuid.ts
-nav_order: 26
+nav_order: 27
 parent: Modules
 ---
 
diff --git a/docs/modules/withMessage.ts.md b/docs/modules/withMessage.ts.md
index 2a18d2c..54319f5 100644
--- a/docs/modules/withMessage.ts.md
+++ b/docs/modules/withMessage.ts.md
@@ -1,6 +1,6 @@
 ---
 title: withMessage.ts
-nav_order: 27
+nav_order: 28
 parent: Modules
 ---
 
diff --git a/docs/modules/withValidate.ts.md b/docs/modules/withValidate.ts.md
index 55bae6a..1fd539d 100644
--- a/docs/modules/withValidate.ts.md
+++ b/docs/modules/withValidate.ts.md
@@ -1,6 +1,6 @@
 ---
 title: withValidate.ts
-nav_order: 28
+nav_order: 29
 parent: Modules
 ---
 
diff --git a/package.json b/package.json
index 1c7c31a..39ce2e5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "io-ts-types",
-  "version": "0.4.3",
+  "version": "0.4.4",
   "description": "A collection of runtime types and combinators for use with io-ts",
   "files": [
     "lib"
@@ -8,11 +8,11 @@
   "main": "lib/index.js",
   "typings": "lib/index.d.ts",
   "scripts": {
-    "lint": "tslint -p tsconfig.json src/**/*.ts test/**/*.ts",
+    "lint": "tslint -p tsconfig.tslint.json src/**/*.ts test/**/*.ts",
     "jest": "jest --coverage",
     "prettier": "prettier --no-semi --single-quote --print-width 120 --parser typescript --list-different \"{src,test}/**/*.ts\" || { echo \"Failure due to formatting, please run 'npm run fix-prettier' to fix this issue\"; exit 1; }",
     "fix-prettier": "prettier --no-semi --single-quote --print-width 120 --parser typescript --write \"{src,test}/**/*.ts\"",
-    "test": "npm run build && npm run lint && npm run dtslint && npm run prettier && npm run jest",
+    "test": "npm run build && npm run lint && npm run dtslint && npm run prettier && npm run jest && npm run docs",
     "clean": "rm -rf lib/*",
     "build": "npm run clean && tsc",
     "dtslint": "dtslint dtslint",
diff --git a/src/IntFromString.ts b/src/IntFromString.ts
new file mode 100644
index 0000000..2181cc8
--- /dev/null
+++ b/src/IntFromString.ts
@@ -0,0 +1,20 @@
+import * as t from 'io-ts'
+import { NumberFromString } from './number/NumberFromString'
+
+/**
+ * A codec that succeeds if a string can be parsed to an integer
+ *
+ * @example
+ * import { IntFromString } from 'io-ts-types/lib/IntFromString'
+ * import { right } from 'fp-ts/lib/Either'
+ * import { PathReporter } from 'io-ts/lib/PathReporter'
+ *
+ * assert.deepStrictEqual(IntFromString.decode('1'), right(1))
+ * assert.deepStrictEqual(PathReporter.report(IntFromString.decode('1.1')), ['Invalid value "1.1" supplied to : IntFromString'])
+ */
+export const IntFromString: t.Type<t.Int, string, unknown> = new t.Type<t.Int, string, unknown>(
+  'IntFromString',
+  t.Int.is,
+  (u, c) => NumberFromString.validate(u, c).chain(n => (t.Int.is(n) ? t.success(n) : t.failure(u, c))),
+  NumberFromString.encode
+)
diff --git a/src/number/IntegerFromString.ts b/src/number/IntegerFromString.ts
index 5993fd5..ed029d1 100644
--- a/src/number/IntegerFromString.ts
+++ b/src/number/IntegerFromString.ts
@@ -4,6 +4,8 @@ import { NumberFromString, NumberFromStringType } from './NumberFromString'
 export interface IntegerFromStringC extends t.RefinementType<NumberFromStringType, number, string, unknown> {}
 
 /**
+ * Use `io-ts-types/lib/IntFromString` instead.
+ *
  * @example
  * import { IntegerFromString } from 'io-ts-types/lib/number/IntegerFromString'
  * import { right } from 'fp-ts/lib/Either'
@@ -11,6 +13,7 @@ export interface IntegerFromStringC extends t.RefinementType<NumberFromStringTyp
  *
  * assert.deepStrictEqual(IntegerFromString.decode('1'), right(1))
  * assert.deepStrictEqual(PathReporter.report(IntegerFromString.decode('1.1')), ['Invalid value 1.1 supplied to : IntegerFromString'])
+ * @deprecated
  */
 // tslint:disable-next-line: deprecation
 export const IntegerFromString: IntegerFromStringC = t.refinement(
diff --git a/tsconfig.tslint.json b/tsconfig.tslint.json
new file mode 100644
index 0000000..b3750f2
--- /dev/null
+++ b/tsconfig.tslint.json
@@ -0,0 +1,7 @@
+{
+  "extends": "./tsconfig.json",
+  "compilerOptions": {
+    "noEmit": true
+  },
+  "include": ["./test/**/*"]
+}


Test patch:
diff --git a/test/IntFromString.ts b/test/IntFromString.ts
new file mode 100644
index 0000000..8cd42cf
--- /dev/null
+++ b/test/IntFromString.ts
@@ -0,0 +1,36 @@
+import * as assert from 'assert'
+import * as t from 'io-ts'
+import { IntFromString } from '../src/IntFromString'
+import { assertSuccess, assertFailure } from './helpers'
+
+describe('fallback', () => {
+  describe('is', () => {
+    it('should check a isomorphic value', () => {
+      const T = IntFromString
+      assert.strictEqual(T.is('a'), false)
+      assert.strictEqual(T.is(1), true)
+      assert.strictEqual(T.is(1.1), false)
+    })
+  })
+
+  describe('decode', () => {
+    it('should succeed validating a valid value', () => {
+      const T = IntFromString
+      assertSuccess(T.decode('1'), 1 as t.Int)
+    })
+
+    it('should fail validation an invalid value', () => {
+      const T = IntFromString
+      assertFailure(T, null, ['Invalid value null supplied to : IntFromString'])
+      assertFailure(T, '1.1', ['Invalid value "1.1" supplied to : IntFromString'])
+      assertFailure(T, '1a', ['Invalid value "1a" supplied to : IntFromString'])
+    })
+  })
+
+  describe('encode', () => {
+    it('should encode a isomorphic value', () => {
+      const T = IntFromString
+      assert.strictEqual(T.encode(1 as t.Int), '1')
+    })
+  })
+})
diff --git a/test/index.ts b/test/index.ts
index 4251d87..1a6afc7 100644
--- a/test/index.ts
+++ b/test/index.ts
@@ -235,6 +235,7 @@ describe('number', () => {
   })
 
   it('IntegerFromString', () => {
+    // tslint:disable-next-line: deprecation
     const T = IntegerFromString
     assert.deepEqual(T.decode('0'), right(0))
     assert.deepEqual(T.decode('10'), right(10))