Socket
Socket
Sign inDemoInstall

io-ts

Package Overview
Dependencies
1
Maintainers
1
Versions
120
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.0.0 to 2.0.1

5

CHANGELOG.md

@@ -17,2 +17,7 @@ # Changelog

# 2.0.1
- **Bug Fix**
- fix `getTags` algorithm for mutually recursive codecs, closes #354 (@gcanti)
# 2.0.0

@@ -19,0 +24,0 @@

45

es6/index.d.ts

@@ -113,6 +113,18 @@ import { Either } from 'fp-ts/lib/Either';

encode: Encode<A, O>);
/**
* @since 1.0.0
*/
pipe<B, IB, A extends IB, OB extends A>(this: Type<A, O, I>, ab: Type<B, OB, IB>, name?: string): Type<B, O, I>;
/**
* @since 1.0.0
*/
asDecoder(): Decoder<I, A>;
/**
* @since 1.0.0
*/
asEncoder(): Encoder<A, O>;
/** a version of `validate` with a default context */
/**
* a version of `validate` with a default context
* @since 1.0.0
*/
decode(i: I): Validation<A>;

@@ -161,3 +173,2 @@ }

/**
* @alias `null`
* @since 1.0.0

@@ -192,3 +203,2 @@ */

/**
* @alias `void`
* @since 1.2.0

@@ -471,3 +481,2 @@ */

/**
* @alias `interface`
* @since 1.0.0

@@ -739,16 +748,30 @@ */

export declare const exact: <C extends HasProps>(codec: C, name?: string) => ExactC<C>;
export { nullType as null };
export { undefinedType as undefined };
export {
/**
* @since 1.0.0
*/
nullType as null };
export {
/**
* @since 1.0.0
*/
undefinedType as undefined };
export {
/**
* Use `UnknownArray` instead
* @deprecated
* @since 1.0.0
*/
export { UnknownArray as Array };
UnknownArray as Array };
export {
/**
* Use `type` instead
* @deprecated
* @since 1.0.0
*/
export { type as interface };
export { voidType as void };
type as interface };
export {
/**
* @since 1.0.0
*/
voidType as void };
/**
* Use `unknown` instead

@@ -755,0 +778,0 @@ * @since 1.0.0

@@ -47,2 +47,5 @@ var __extends = (this && this.__extends) || (function () {

}
/**
* @since 1.0.0
*/
Type.prototype.pipe = function (ab, name) {

@@ -53,9 +56,18 @@ var _this = this;

};
/**
* @since 1.0.0
*/
Type.prototype.asDecoder = function () {
return this;
};
/**
* @since 1.0.0
*/
Type.prototype.asEncoder = function () {
return this;
};
/** a version of `validate` with a default context */
/**
* a version of `validate` with a default context
* @since 1.0.0
*/
Type.prototype.decode = function (i) {

@@ -136,3 +148,2 @@ return this.validate(i, [{ key: '', type: this, actual: i }]);

/**
* @alias `null`
* @since 1.0.0

@@ -169,3 +180,2 @@ */

/**
* @alias `void`
* @since 1.2.0

@@ -483,3 +493,2 @@ */

/**
* @alias `interface`
* @since 1.0.0

@@ -1056,17 +1065,31 @@ */

};
export { nullType as null };
export { undefinedType as undefined };
export {
/**
* @since 1.0.0
*/
nullType as null };
export {
/**
* @since 1.0.0
*/
undefinedType as undefined };
export {
/**
* Use `UnknownArray` instead
* @deprecated
* @since 1.0.0
*/
export { UnknownArray as Array };
UnknownArray as Array };
export {
/**
* Use `type` instead
* @deprecated
* @since 1.0.0
*/
export { type as interface };
export { voidType as void };
type as interface };
export {
/**
* @since 1.0.0
*/
voidType as void };
/**
* @since 1.0.0
* @deprecated

@@ -1295,3 +1318,3 @@ */

}
var lazyCodec = null;
var lazyCodecs = [];
/**

@@ -1301,3 +1324,3 @@ * @internal

export function getTags(codec) {
if (codec === lazyCodec) {
if (lazyCodecs.indexOf(codec) !== -1) {
return emptyTags;

@@ -1329,5 +1352,5 @@ }

else if (isRecursiveC(codec)) {
lazyCodec = codec;
lazyCodecs.push(codec);
var tags = getTags(codec.type);
lazyCodec = null;
lazyCodecs.pop();
return tags;

@@ -1334,0 +1357,0 @@ }

@@ -113,6 +113,18 @@ import { Either } from 'fp-ts/lib/Either';

encode: Encode<A, O>);
/**
* @since 1.0.0
*/
pipe<B, IB, A extends IB, OB extends A>(this: Type<A, O, I>, ab: Type<B, OB, IB>, name?: string): Type<B, O, I>;
/**
* @since 1.0.0
*/
asDecoder(): Decoder<I, A>;
/**
* @since 1.0.0
*/
asEncoder(): Encoder<A, O>;
/** a version of `validate` with a default context */
/**
* a version of `validate` with a default context
* @since 1.0.0
*/
decode(i: I): Validation<A>;

@@ -161,3 +173,2 @@ }

/**
* @alias `null`
* @since 1.0.0

@@ -192,3 +203,2 @@ */

/**
* @alias `void`
* @since 1.2.0

@@ -471,3 +481,2 @@ */

/**
* @alias `interface`
* @since 1.0.0

@@ -739,16 +748,30 @@ */

export declare const exact: <C extends HasProps>(codec: C, name?: string) => ExactC<C>;
export { nullType as null };
export { undefinedType as undefined };
export {
/**
* @since 1.0.0
*/
nullType as null };
export {
/**
* @since 1.0.0
*/
undefinedType as undefined };
export {
/**
* Use `UnknownArray` instead
* @deprecated
* @since 1.0.0
*/
export { UnknownArray as Array };
UnknownArray as Array };
export {
/**
* Use `type` instead
* @deprecated
* @since 1.0.0
*/
export { type as interface };
export { voidType as void };
type as interface };
export {
/**
* @since 1.0.0
*/
voidType as void };
/**
* Use `unknown` instead

@@ -755,0 +778,0 @@ * @since 1.0.0

@@ -49,2 +49,5 @@ "use strict";

}
/**
* @since 1.0.0
*/
Type.prototype.pipe = function (ab, name) {

@@ -55,9 +58,18 @@ var _this = this;

};
/**
* @since 1.0.0
*/
Type.prototype.asDecoder = function () {
return this;
};
/**
* @since 1.0.0
*/
Type.prototype.asEncoder = function () {
return this;
};
/** a version of `validate` with a default context */
/**
* a version of `validate` with a default context
* @since 1.0.0
*/
Type.prototype.decode = function (i) {

@@ -138,3 +150,2 @@ return this.validate(i, [{ key: '', type: this, actual: i }]);

/**
* @alias `null`
* @since 1.0.0

@@ -173,3 +184,2 @@ */

/**
* @alias `void`
* @since 1.2.0

@@ -489,3 +499,2 @@ */

/**
* @alias `interface`
* @since 1.0.0

@@ -1293,3 +1302,3 @@ */

}
var lazyCodec = null;
var lazyCodecs = [];
/**

@@ -1299,3 +1308,3 @@ * @internal

function getTags(codec) {
if (codec === lazyCodec) {
if (lazyCodecs.indexOf(codec) !== -1) {
return exports.emptyTags;

@@ -1327,5 +1336,5 @@ }

else if (isRecursiveC(codec)) {
lazyCodec = codec;
lazyCodecs.push(codec);
var tags = getTags(codec.type);
lazyCodec = null;
lazyCodecs.pop();
return tags;

@@ -1332,0 +1341,0 @@ }

{
"name": "io-ts",
"version": "2.0.0",
"version": "2.0.1",
"description": "TypeScript compatible runtime type system for IO validation",

@@ -47,3 +47,3 @@ "files": [

"benchmark": "2.1.4",
"docs-ts": "^0.1.0",
"docs-ts": "^0.2.1",
"doctoc": "^1.4.0",

@@ -50,0 +50,0 @@ "dtslint": "github:gcanti/dtslint",

@@ -13,7 +13,6 @@ [![build status](https://img.shields.io/travis/gcanti/io-ts/master.svg?style=flat-square)](https://travis-ci.org/gcanti/io-ts)

- [The idea](#the-idea)
- [TypeScript integration](#typescript-integration)
- [TypeScript compatibility](#typescript-compatibility)
- [Error reporters](#error-reporters)
- [Custom error messages](#custom-error-messages)
- [Community](#community)
- [TypeScript integration](#typescript-integration)
- [Implemented types / combinators](#implemented-types--combinators)

@@ -28,4 +27,4 @@ - [Recursive types](#recursive-types)

- [Piping](#piping)
- [Community](#community)
- [Tips and Tricks](#tips-and-tricks)
- [Is there a way to turn the checks off in production code?](#is-there-a-way-to-turn-the-checks-off-in-production-code)
- [Union of string literals](#union-of-string-literals)

@@ -40,32 +39,33 @@

```sh
npm i io-ts
npm i io-ts fp-ts
```
Note: [`fp-ts`](https://github.com/gcanti/fp-ts) is a peer dependency for `io-ts`
# The idea
Blog post: ["Typescript and validations at runtime boundaries"](https://lorefnon.tech/2018/03/25/typescript-and-validations-at-runtime-boundaries/) by [@lorefnon](https://github.com/lorefnon)
A value of type `Type<A, O, I>` (called "codec") is the runtime representation of the static type `A`.
Also a codec can
A codec can:
- decode inputs of type `I` (through `decode`)
- encode outputs of type `O` (through `encode`)
- be used as a custom type guard (through `is`)
- be used as a custom [type guard](https://basarat.gitbooks.io/typescript/content/docs/types/typeGuard.html) (through `is`)
```ts
class Type<A, O, I> {
readonly _A: A
readonly _O: O
readonly _I: I
constructor(
/** a unique name for this codec */
readonly name: string,
/** a custom type guard */
readonly is: (u: unknown) => u is A,
/** succeeds if a value of type I can be decoded to a value of type A */
readonly validate: (input: I, context: Context) => Either<Errors, A>,
/** converts a value of type A to a value of type O */
readonly encode: (a: A) => O
) {}
/** a version of `validate` with a default context */

@@ -76,8 +76,23 @@ decode(i: I): Either<Errors, A>

Note. The `Either` type is defined in [fp-ts](https://github.com/gcanti/fp-ts), a library containing implementations of
common algebraic types in TypeScript.
The [`Either`](https://gcanti.github.io/fp-ts/modules/Either.ts.html) type returned by `decode` is defined in [fp-ts](https://github.com/gcanti/fp-ts), a library containing implementations of common algebraic types in TypeScript.
The `Either` type represents a value of one of two possible types (a disjoint union). An instance of `Either` is either an instance of `Left` or `Right`:
```ts
type Either<E, A> =
| {
readonly _tag: 'Left'
readonly left: E
}
| {
readonly _tag: 'Right'
readonly right: A
}
```
Convention dictates that `Left` is used for **failure** and `Right` is used for **success**.
**Example**
A codec representing `string` can be defined as
A codec representing `string` can be defined as:

@@ -87,8 +102,8 @@ ```ts

const isString = (u: unknown): u is string => typeof u === 'string'
const string = new t.Type<string, string, unknown>(
'string',
isString,
(u, c) => (isString(u) ? t.success(u) : t.failure(u, c)),
(input: unknown): input is string => typeof input === 'string',
// `t.success` and `t.failure` are helpers used to build `Either` instances
(input, context) => (typeof input === 'string' ? t.success(input) : t.failure(input, context)),
// `A` and `O` are the same, so `encode` is just the identity function
t.identity

@@ -98,7 +113,42 @@ )

A codec can be used to validate an object in memory (for example an API payload)
and we can use it as follows:
```ts
import { isRight } from 'fp-ts/lib/Either'
isRight(string.decode('a string')) // true
isRight(string.decode(null)) // false
```
More generally the result of calling `decode` can be handled using [`fold`](https://gcanti.github.io/fp-ts/modules/Either.ts.html#fold-function) along with `pipe` (which is similar to the pipeline operator)
```ts
import * as t from 'io-ts'
import { pipe } from 'fp-ts/lib/pipeable'
import { fold } from 'fp-ts/lib/Either'
// failure handler
const onLeft = (errors: t.Errors): string => `${errors.length} error(s) found`
// success handler
const onRight = (s: string) => `No errors: ${s}`
pipe(
t.string.decode('a string'),
fold(onLeft, onRight)
)
// => "No errors: a string"
pipe(
t.string.decode(null),
fold(onLeft, onRight)
)
// => "1 error(s) found"
```
We can combine these codecs through [combinators](#implemented-types--combinators) to build composite types which represent entities like domain models, request payloads etc. in our applications:
```ts
import * as t from 'io-ts'
const User = t.type({

@@ -108,10 +158,40 @@ userId: t.number,

})
```
// validation succeeded
User.decode(JSON.parse('{"userId":1,"name":"Giulio"}')) // => Right({ userId: 1, name: "Giulio" })
So this is equivalent to defining something like:
// validation failed
User.decode(JSON.parse('{"name":"Giulio"}')) // => Left([...])
```ts
type User = {
userId: number
name: string
}
```
The advantage of using `io-ts` to define the runtime type is that we can validate the type at runtime, and we can also extract the corresponding static type, so we don’t have to define it twice.
# TypeScript integration
Codecs can be inspected:
![instrospection](images/introspection.png)
This library uses TypeScript extensively. Its API is defined in a way which automatically infers types for produced
values
![inference](images/inference.png)
Note that the type annotation isn't needed, TypeScript infers the type automatically based on a schema (and comments are preserved).
Static types can be extracted from codecs using the `TypeOf` operator:
```ts
type User = t.TypeOf<typeof User>
// same as
type User = {
userId: number
name: string
}
```
# TypeScript compatibility

@@ -217,39 +297,2 @@

# Community
- `io-ts@1.x`
- [io-ts-types](https://github.com/gcanti/io-ts-types) - A collection of codecs and combinators for use with
io-ts
- [io-ts-reporters](https://github.com/OliverJAsh/io-ts-reporters) - Error reporters for io-ts
- [geojson-iots](https://github.com/pierremarc/geojson-iots) - codecs for GeoJSON as defined in rfc7946 made with
io-ts
- [graphql-to-io-ts](https://github.com/micimize/graphql-to-io-ts) - Generate typescript and cooresponding io-ts types from a graphql
schema
- [io-ts-promise](https://github.com/aeirola/io-ts-promise) - Convenience library for using io-ts with promise-based APIs
# TypeScript integration
codecs can be inspected
![instrospection](images/introspection.png)
This library uses TypeScript extensively. Its API is defined in a way which automatically infers types for produced
values
![inference](images/inference.png)
Note that the type annotation isn't needed, TypeScript infers the type automatically based on a schema (and comments are preserved).
Static types can be extracted from codecs using the `TypeOf` operator
```ts
type User = t.TypeOf<typeof User>
// same as
type User = {
userId: number
name: string
}
```
# Implemented types / combinators

@@ -266,4 +309,2 @@

| unknown | `unknown` | `t.unknown` |
| never | `never` | `t.never` |
| object | `object` | `t.object` |
| array of unknown | `Array<unknown>` | `t.UnknownArray` |

@@ -283,3 +324,3 @@ | array of type | `Array<A>` | `t.array(A)` |

| keyof | `keyof M` | `t.keyof(M)` (**only supports string keys**) |
| recursive types | ✘ | `t.recursion(name, definition)` |
| recursive types | | `t.recursion(name, definition)` |
| branded types / refinements | ✘ | `t.brand(A, predicate, brand)` |

@@ -515,2 +556,14 @@ | integer | ✘ | `t.Int` (built-in branded codec) |

# Community
- `io-ts@1.x`
- [io-ts-types](https://github.com/gcanti/io-ts-types) - A collection of codecs and combinators for use with
io-ts
- [io-ts-reporters](https://github.com/OliverJAsh/io-ts-reporters) - Error reporters for io-ts
- [geojson-iots](https://github.com/pierremarc/geojson-iots) - codecs for GeoJSON as defined in rfc7946 made with
io-ts
- [graphql-to-io-ts](https://github.com/micimize/graphql-to-io-ts) - Generate typescript and cooresponding io-ts types from a graphql
schema
- [io-ts-promise](https://github.com/aeirola/io-ts-promise) - Convenience library for using io-ts with promise-based APIs
# Tips and Tricks

@@ -517,0 +570,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc