Skip to content

Commit

Permalink
update documentation and bump version
Browse files Browse the repository at this point in the history
  • Loading branch information
gcanti committed Feb 8, 2018
1 parent 50c3854 commit b641126
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 15 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Expand Up @@ -13,6 +13,13 @@
**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.

# 0.9.8

* **New Feature**
* add decode and deprecate top level validate (@gcanti)
* **Internal**
* when checking validations use methods instead of top level functions (@gcanti)

# 0.9.7

* **New Feature**
Expand Down
24 changes: 13 additions & 11 deletions README.md
Expand Up @@ -8,7 +8,7 @@ A value of type `Type<S, A>` (called "runtime type") is the runtime representati

Also a runtime type can

* decode inputs (through `validate`)
* decode inputs (through `decode`)
* encode outputs (through `serialize`)
* be used as a custom type guard (through `is`)

Expand All @@ -28,6 +28,8 @@ class Type<S, A> {
/** converts a value of type A to a value of type S */
readonly serialize: (output: A) => S
) {}
/** a version of `validate` with a default context */
decode(s: S): Either<Errors, A>
}
```

Expand Down Expand Up @@ -62,10 +64,10 @@ const Person = t.interface({
})

// ok
t.validate(JSON.parse('{"name":"Giulio","age":43}'), Person) // => Right({name: "Giulio", age: 43})
Person.decode(JSON.parse('{"name":"Giulio","age":43}')) // => Right({name: "Giulio", age: 43})

// ko
t.validate(JSON.parse('{"name":"Giulio"}'), Person) // => Left([...])
Person.decode(JSON.parse('{"name":"Giulio"}')) // => Left([...])
```

# Error reporters
Expand All @@ -89,12 +91,12 @@ Example
import { PathReporter } from 'io-ts/lib/PathReporter'
import { ThrowReporter } from 'io-ts/lib/ThrowReporter'

const validation = t.validate({ name: 'Giulio' }, Person)
const result = Person.decode({ name: 'Giulio' })

console.log(PathReporter.report(validation))
console.log(PathReporter.report(result))
// => ['Invalid value undefined supplied to : { name: string, age: number }/age: number']

ThrowReporter.report(validation)
ThrowReporter.report(result)
// => throws 'Invalid value undefined supplied to : { name: string, age: number }/age: number'
```

Expand Down Expand Up @@ -231,8 +233,8 @@ const Person = t.interface({

const StrictPerson = t.strict(Person.props)

t.validate({ name: 'Giulio', age: 43, surname: 'Canti' }, Person) // ok
t.validate({ name: 'Giulio', age: 43, surname: 'Canti' }, StrictPerson) // fails
Person.decode({ name: 'Giulio', age: 43, surname: 'Canti' }) // ok
StrictPerson.decode({ name: 'Giulio', age: 43, surname: 'Canti' }) // fails
```

# Mixing required and optional props
Expand Down Expand Up @@ -297,10 +299,10 @@ const DateFromString = new t.Type<t.mixed, Date>(

const s = new Date(1973, 10, 30).toISOString()

t.validate(s, DateFromString)
DateFromString.decode(s)
// right(new Date('1973-11-29T23:00:00.000Z'))

t.validate('foo', DateFromString)
DateFromString.decode('foo')
// left(errors...)
```

Expand Down Expand Up @@ -366,7 +368,7 @@ const { NODE_ENV } = process.env

export function unsafeValidate<S, A>(value: any, type: t.Type<S, A>): A {
if (NODE_ENV !== 'production') {
return t.validate(value, type).getOrElse(errors => {
return type.decode(value).getOrElse(errors => {
throw new Error(failure(errors).join('\n'))
})
}
Expand Down
Binary file modified docs/images/inference.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "io-ts",
"version": "0.9.7",
"version": "0.9.8",
"description": "TypeScript compatible runtime type system for IO validation",
"files": ["lib"],
"main": "lib/index.js",
Expand Down
6 changes: 3 additions & 3 deletions src/index.ts
Expand Up @@ -40,8 +40,8 @@ export interface Encoder<S, A> {

/**
* Laws:
* 1. validate(x, T).fold(() => x, T.serialize) = x
* 2. validate(T.serialize(x), T) = Right(x)
* 1. T.decode(x).fold(() => x, T.serialize) = x
* 2. T.decode(T.serialize(x)) = right(x)
*
* where `T` is a runtime type
*/
Expand Down Expand Up @@ -76,7 +76,7 @@ export class Type<S, A> implements Decoder<S, A>, Encoder<S, A> {
asEncoder(): Encoder<S, A> {
return this
}
/** succeeds if a value of type S can be decoded to a value of type A */
/** a version of `validate` with a default context */
decode(s: S): Validation<A> {
return this.validate(s, getDefaultContext(this))
}
Expand Down
11 changes: 11 additions & 0 deletions typings-checker/index.ts
Expand Up @@ -310,3 +310,14 @@ const TU1 = t.taggedUnion('type', [t.type({ type: t.literal('a') }), t.type({ ty
const x36: TypeOf<typeof TU1> = true
const x37: TypeOf<typeof TU1> = { type: 'a' }
const x38: TypeOf<typeof TU1> = { type: 'b' }

export function interfaceWithOptionals<R extends t.Props, O extends t.Props>(
required: R,
optional: O,
name?: string
): t.IntersectionType<
[t.InterfaceType<R, t.InterfaceOf<R>>, t.PartialType<O, t.PartialOf<O>>],
t.InterfaceOf<R> & t.PartialOf<O>
> {
return t.intersection([t.interface(required), t.partial(optional)], name)
}

0 comments on commit b641126

Please sign in to comment.