Repository: gcanti/tcomb
Pull request #230 (2016-07-14 05:39:02)

add support for class constructors, `fromJSON` module


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c6ab378..83af504 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,12 @@
 **Note**: Gaps between patch versions are faulty/broken releases.
 **Note**: A feature tagged as Experimental is in a high state of flux, you're at risk of it changing without notice.
 
+# 3.2.7
+
+- **Bug Fix**
+  - add support for class constructors, `fromJSON` module (@gcanti)
+  - type-check the value returned by a custom reviver, `fromJSON` module (@gcanti)
+
 # v3.2.6
 
 - **Bug Fix**
diff --git a/docs/API.md b/docs/API.md
index adfc4b0..6e659d6 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -1046,15 +1046,9 @@ import fromJSON from 'tcomb/lib/fromJSON'
 
 const Person = t.struct({
   name: t.String,
-  birthDate: t.Date
+  birthDate: Date
 });
 
-// configure your types
-t.Date.fromJSON = function (s) {
-  t.assert(t.String.is(s));
-  return new Date(s);
-};
-
 const source = {
   name: 'Giulio',
   birthDate: new Date(1973, 10, 30)
@@ -1070,6 +1064,8 @@ assert.ok(person instanceof Person); // => true
 assert.deepEqual(person, source); // => ok
 ```
 
+You can add a static `fromJSON: (jsonValue: any) => any` function to your types as a custom reviver.
+
 ## The `lib/installTypeFormatter` module
 
 Chrome Dev Tools custom formatter for tcomb types.
diff --git a/lib/fromJSON.js b/lib/fromJSON.js
index cf2a454..6ea7c79 100644
--- a/lib/fromJSON.js
+++ b/lib/fromJSON.js
@@ -4,6 +4,7 @@ var isNil = require('./isNil');
 var getTypeName = require('./getTypeName');
 var isObject = require('./isObject');
 var isArray = require('./isArray');
+var isType = require('./isType');
 
 function fromJSON(value, type) {
   if (process.env.NODE_ENV !== 'production') {
@@ -13,7 +14,11 @@ function fromJSON(value, type) {
   }
 
   if (isFunction(type.fromJSON)) {
-    return type.fromJSON(value);
+    return type(type.fromJSON(value));
+  }
+
+  if (!isType(type)) {
+    return value instanceof type ? value : new type(value);
   }
 
   var kind = type.meta.kind;
diff --git a/package.json b/package.json
index 0187446..798724d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "tcomb",
-  "version": "3.2.6",
+  "version": "3.2.7",
   "description": "Type checking and DDD for JavaScript",
   "main": "index.js",
   "typings": "index.d.ts",


Test patch:
diff --git a/test/fromJSON.js b/test/fromJSON.js
index 1c27209..e103576 100644
--- a/test/fromJSON.js
+++ b/test/fromJSON.js
@@ -27,9 +27,16 @@ describe('fromJSON', function () {
   it('should handle a static fromJSON function attached to the type', function () {
     var MyType = t.refinement(t.String, function () { return true; });
     MyType.fromJSON = function (s) {
-      return s.length;
+      return s + 'ok';
     };
-    assert.equal(fromJSON('aaa', MyType), 3);
+    assert.equal(fromJSON('aaa', MyType), 'aaaok');
+  });
+
+  it('should handle class constructors', function () {
+    var expected = '1973-11-30T00:00:00.000Z';
+    assert.strictEqual(fromJSON('1973-11-30T00:00:00.000Z', Date).toISOString(), expected);
+    var actual = new RegExp('a');
+    assert.strictEqual(fromJSON(actual, RegExp), actual);
   });
 
   it('should handle maybe', function () {