All Projects → kawmra → typist-json

kawmra / typist-json

Licence: MIT license
A simple runtime JSON type checker.

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to typist-json

pyrser
A PEG Parsing Tool
Stars: ✭ 32 (+28%)
Mutual labels:  type-checking, type-checker
Typology
Swift type checking and semantic analysis for developer tools
Stars: ✭ 68 (+172%)
Mutual labels:  type-checking, type-checker
Ts Toolbelt
ts-toolbelt is the largest, and most tested type library available right now, featuring +200 utilities. Our type collection packages some of the most advanced mapped types, conditional types, and recursive types on the market.
Stars: ✭ 3,099 (+12296%)
Mutual labels:  typescript-library, type-checking
EffectiveSan
Runtime type and bounds-error checking for C/C++
Stars: ✭ 95 (+280%)
Mutual labels:  type-checking
microbundle-ts-pkg
A TypeScript npm package skeleton/starter project with microbundle, node:test and prettier
Stars: ✭ 20 (-20%)
Mutual labels:  typescript-library
IntelliJ-Luanalysis
Type-safe Lua IDE Plugin for IntelliJ IDEA
Stars: ✭ 118 (+372%)
Mutual labels:  type-checking
typescript-strict-plugin
Typescript plugin that allows turning on strict mode in specific files or directories.
Stars: ✭ 166 (+564%)
Mutual labels:  typescript-library
Useworker
⚛️ useWorker() - A React Hook for Blocking-Free Background Tasks
Stars: ✭ 2,233 (+8832%)
Mutual labels:  typescript-library
imtool
🖼️ Client-side canvas-based image manipulation library.
Stars: ✭ 38 (+52%)
Mutual labels:  typescript-library
alls
Just another library with the sole purpose of waiting till all promises to complete. Nothing more, Nothing less.
Stars: ✭ 13 (-48%)
Mutual labels:  typescript-library
re-reduced
Productivity toolbelt for React/Redux/Redux-Saga apps. 1.7kb minzipped
Stars: ✭ 15 (-40%)
Mutual labels:  type-safe
SwiftyJSONModel
Better way to use SwiftyJSON with custom models
Stars: ✭ 29 (+16%)
Mutual labels:  type-safe
tiny-typed-emitter
Fully type-checked NodeJS EventEmitter
Stars: ✭ 96 (+284%)
Mutual labels:  typescript-library
typeforce
Another biased type checking solution for Javascript
Stars: ✭ 22 (-12%)
Mutual labels:  type-checking
ifto
A simple debugging module for AWS Lambda (λ) timeout
Stars: ✭ 72 (+188%)
Mutual labels:  typescript-library
ts-mock-imports
Intuitive mocking library for Typescript class imports
Stars: ✭ 103 (+312%)
Mutual labels:  typescript-library
necktie
Necktie – a simple DOM binding tool
Stars: ✭ 43 (+72%)
Mutual labels:  typescript-library
serialize
Serializers for typescript based on decorators
Stars: ✭ 14 (-44%)
Mutual labels:  typescript-library
storken
🦩 Storken is a React State Manager. Simple as `useState`.
Stars: ✭ 22 (-12%)
Mutual labels:  typescript-library
dataStructure
Implement different Data Structures using TypeScript and JavaScript. Deno Third-party Module.
Stars: ✭ 24 (-4%)
Mutual labels:  typescript-library

Typist JSON

minzipped size types license ci

A simple runtime JSON type checker.

Features

  • Simple. No JSON Schema, No validation rules
  • Type-safe. Written in TypeScript
  • Intuitive. Familiar syntax like TypeScript interface

Typist JSON is focused on type checking, so there is no validation rules like range of numbers or length of strings.

Install

npm install typist-json

NOTE: Require TypeScript 4.1 or higher because Typist JSON uses Key Remapping and Template Literal Types.

Example

import { j } from "typist-json";

const NameJson = j.object({
  firstname: j.string,
  lastname: j.string,
});

const UserJson = j.object({
  name: NameJson,
  age: j.number,
  "nickname?": j.string, // optional property
});

const userJson = await fetch("/api/user")
    .then(res => res.json());

if (UserJson.check(userJson)) {
  // now, the userJson is narrowed to:
  // {
  //   name: {
  //     firstname: string
  //     lastname: string
  //   }
  //   age: number
  //   nickname?: string | undefined
  // }
}

Circular References

Sometimes JSON structures can form circular references.

Typist JSON can represent circular references by wrapping checkers in the arrow function.

const FileJson = j.object({
  filename: j.string,
});

const DirJson = j.object({
  dirname: j.string,
  entries: () => j.array(j.any([FileJson, DirJson])), // references itself
});

DirJson.check({
  dirname: "animals",
  entries: [
    {
      dirname: "cat",
      entries: [
        { filename: "american-shorthair.jpg" },
        { filename: "munchkin.jpg" },
        { filename: "persian.jpg" },
      ],
    },
    {
      dirname: "dog",
      entries: [
        { filename: "chihuahua.jpg" },
        { filename: "pug.jpg" },
        { filename: "shepherd.jpg" },
      ],
    },
    { filename: "turtle.jpg" },
    { filename: "shark.jpg" },
  ],
}); // true

Type checkers

Strings

j.string.check("foo"); // true
j.string.check("bar"); // true

Numbers

j.number.check(42); // true
j.number.check(12.3); // true
j.number.check("100"); // false

Booleans

j.boolean.check(true); // true
j.boolean.check(false); // true

Literals

j.literal("foo").check("foo"); // true
j.literal("foo").check("fooooo"); // false

Arrays

j.array(j.string).check(["foo", "bar"]); // true
j.array(j.string).check(["foo", 42]); // false
j.array(j.string).check([]); // true
j.array(j.number).check([]); // true

Objects

j.object({
  name: j.string,
  age: j.number,
  "nickname?": j.string,
}).check({
  name: "John",
  age: 20,
  nickname: "Johnny",
}); // true

j.object({
  name: j.string,
  age: j.number,
  "nickname?": j.string,
}).check({
  name: "Emma",
  age: 20,
}); // true, since "nickname" is optional

j.object({
  name: j.string,
  age: j.number,
  "nickname?": j.string,
}).check({
  id: "xxxx",
  type: "android",
}); // false, since "name" and "age" is required

If a property that ends with ? is not optional, you should replace all trailing ? by ??.

More details about escaping

As mentioned above, you need to escape all trailing ? as ??.

j.object({
    "foo??": j.boolean,
}).check({
    "foo?": true,
}); // true

So if you want optional property with a name "foo???", you should use "foo???????" as key.

j.object({
  "foo???????": j.boolean,
}).check({}); // true, since "foo???" is optional

Nulls

j.nil.check(null); // true
j.nil.check(undefined); // false

Nullables

j.nullable(j.string).check("foo"); // true
j.nullable(j.string).check(null); // true
j.nullable(j.string).check(undefined); // false

Unknowns

j.unknown.check("foo"); // true
j.unknown.check(123); // true
j.unknown.check(null); // true
j.unknown.check(undefined); // true
j.unknown.check([{}, 123, false, "foo"]); // true

Unions

j.any([j.string, j.boolean]).check(false); // true

j.any([
  j.literal("foo"),
  j.literal("bar"),
]).check("foo"); // true

Get JSON type of checkers

import { j, JsonTypeOf } from "typist-json";

const UserJson = j.object({
  name: j.string,
  age: j.number,
  "nickname?": j.string,
});

type UserJsonType = JsonTypeOf<typeof UserJson>;
// 
// ^ This is same as:
// 
// type UserJsonType = {
//   name: string;
//   age: number;
//   nickname?: string;
// }
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].