Skip to content

Instantly share code, notes, and snippets.

@mluisbrown
Last active October 11, 2017 11:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mluisbrown/27556589aa5862324af576b3d97628d8 to your computer and use it in GitHub Desktop.
Save mluisbrown/27556589aa5862324af576b3d97628d8 to your computer and use it in GitHub Desktop.
Simple JSON validation example using RamdaJS and fp-ts with Typescript
import { both, converge, equals as eq, ifElse, not, pipe, toLower, type, keys, curry } from "ramda"
import { Either, left, right, isLeft, isRight, getOrElse } from "fp-ts/lib/Either"
export type Json = string|number|boolean|Date|JsonObject
interface JsonObject {
[x: string]: Json;
}
interface JsonArray extends Array<Json> { }
export type Schema = { [id: string] : string }
const nameAndAgeSchema: Schema = {
name: "string",
age: "number"
}
const validRequest: Json = {
name: "Michael",
age: 48
}
const invalidRequest: Json = {
name: 123,
age: "Hello"
}
const validType: (t: string) => (value: Json) => Either<string[], Json> = t =>
ifElse(
both(pipe(eq(undefined), not), pipe(type, toLower, eq(t))),
right,
a => left([`${a} is not a valid ${t}`]))
function validInput(schema: Schema, input: Json): Either<string[], Json> {
return keys(input)
.map(k => validType(schema[k])(input[k]))
.reduce((acc, element): Either<string[], Json> =>
element.fold(
e => isLeft(acc) ? acc.mapLeft(l => l.concat(e)) : left(e),
j => acc
)
, right(input))
}
const validNameAndAge = curry(validInput)(nameAndAgeSchema)
console.log(validNameAndAge(validRequest).value) // => { name: 'Michael', age: 48 }
console.log(validNameAndAge(invalidRequest).value) // => [ '123 is not a valid string', 'Hello is not a valid number' ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment