Package Exports
- typist-json
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (typist-json) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Typist JSON
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-jsonNOTE: 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" },
],
}); // trueType checkers
Strings
j.string.check("foo"); // true
j.string.check("bar"); // trueNumbers
j.number.check(42); // true
j.number.check(12.3); // true
j.number.check("100"); // falseBooleans
j.boolean.check(true); // true
j.boolean.check(false); // trueLiterals
j.literal("foo").check("foo"); // true
j.literal("foo").check("fooooo"); // falseArrays
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([]); // trueObjects
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 requiredIf 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,
}); // trueSo 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 optionalNulls
j.nil.check(null); // true
j.nil.check(undefined); // falseNullables
j.nullable(j.string).check("foo"); // true
j.nullable(j.string).check(null); // true
j.nullable(j.string).check(undefined); // falseUnknowns
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"]); // trueUnions
j.any([j.string, j.boolean]).check(false); // true
j.any([
j.literal("foo"),
j.literal("bar"),
]).check("foo"); // trueGet 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;
// }