Repository: gcanti/io-ts
Pull request #186 (2018-07-04 10:33:27)

New Feature: add `void` runtime type


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bf3c1a4..e9603f4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,11 @@
 **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.
 
+# 1.2.0
+
+- **New Feature**
+  - add `void` runtime type (@gcanti)
+
 # 1.1.5
 
 - **Bug Fix**
diff --git a/README.md b/README.md
index 17f6ede..d3e16bb 100644
--- a/README.md
+++ b/README.md
@@ -158,6 +158,7 @@ import * as t from 'io-ts'
 | ------------------------- | --------------------------------------- | ----------------------------------------------------- |
 | null                      | `null`                                  | `t.null` or `t.nullType`                              |
 | undefined                 | `undefined`                             | `t.undefined`                                         |
+| void                      | `void`                                  | `t.void` or `t.voidType`                              |
 | string                    | `string`                                | `t.string`                                            |
 | number                    | `number`                                | `t.number`                                            |
 | boolean                   | `boolean`                               | `t.boolean`                                           |
diff --git a/dtslint/index.ts b/dtslint/index.ts
index af87b3a..177b1b5 100644
--- a/dtslint/index.ts
+++ b/dtslint/index.ts
@@ -397,3 +397,20 @@ export const Action = t.union([
 
 const ActionType = pluck(Action, 'type')
 type Assert20 = t.TypeOf<typeof ActionType> // $ExpectType "Action1" | "Action2"
+
+//
+// void
+//
+
+import { TaskEither } from 'fp-ts/lib/TaskEither'
+
+declare function withValidation<L, A>(
+  type: t.Type<A>,
+  f: (errors: t.Errors) => L,
+  fa: TaskEither<L, A>
+): TaskEither<L, A>
+
+// tslint:disable-next-line:void-return
+declare const fa: TaskEither<string, void>
+
+withValidation(t.void, () => 'validation error', fa)
diff --git a/package.json b/package.json
index 06c9c94..c63916e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "io-ts",
-  "version": "1.1.5",
+  "version": "1.2.0",
   "description": "TypeScript compatible runtime type system for IO validation",
   "files": [
     "lib"
diff --git a/src/index.ts b/src/index.ts
index b0ce640..86b29b1 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -7,7 +7,7 @@ declare global {
   }
 }
 
-export type mixed = { [key: string]: any } | object | number | string | boolean | symbol | undefined | null
+export type mixed = { [key: string]: any } | object | number | string | boolean | symbol | undefined | null | void
 
 export interface ContextEntry {
   readonly key: string
@@ -144,6 +144,16 @@ export class UndefinedType extends Type<undefined> {
 
 const undefinedType: UndefinedType = new UndefinedType()
 
+export class VoidType extends Type<void> {
+  readonly _tag: 'VoidType' = 'VoidType'
+  constructor() {
+    super('void', undefinedType.is, undefinedType.validate, identity)
+  }
+}
+
+/** @alias `void` */
+export const voidType: VoidType = new VoidType()
+
 export class AnyType extends Type<any> {
   readonly _tag: 'AnyType' = 'AnyType'
   constructor() {
@@ -1281,4 +1291,4 @@ export function alias<A, O, I>(
   return () => type as any
 }
 
-export { nullType as null, undefinedType as undefined, arrayType as Array, type as interface }
+export { nullType as null, undefinedType as undefined, arrayType as Array, type as interface, voidType as void }


Test patch:
diff --git a/test/default-types.ts b/test/default-types.ts
index a1eca27..62553c8 100644
--- a/test/default-types.ts
+++ b/test/default-types.ts
@@ -35,8 +35,15 @@ describe('Integer', () => {
 
 describe('null', () => {
   it('should support the alias `nullType`', () => {
-    assertSuccess(t.null.decode(null))
-    assertFailure(t.null.decode(1), ['Invalid value 1 supplied to : null'])
+    assertSuccess(t.nullType.decode(null))
+    assertFailure(t.nullType.decode(1), ['Invalid value 1 supplied to : null'])
+  })
+})
+
+describe('void', () => {
+  it('should support the alias `voidType`', () => {
+    assertSuccess(t.voidType.decode(undefined))
+    assertFailure(t.voidType.decode(1), ['Invalid value 1 supplied to : void'])
   })
 })