Skip to content

Commit

Permalink
Merge pull request #195 from samchon/v3.2
Browse files Browse the repository at this point in the history
Close #187, support equivalent validator function
  • Loading branch information
samchon authored Sep 18, 2022
2 parents a945c56 + 61d5d14 commit fccd66e
Show file tree
Hide file tree
Showing 144 changed files with 2,231 additions and 282 deletions.
56 changes: 47 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# TypeScript-JSON
Super-fast Runtime type checker and `JSON.stringify()` functions, with only one line.
Super-fast Runtime validators and `JSON.stringify()` functions, with only one line.

[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/typescript-json/blob/master/LICENSE)
[![npm version](https://img.shields.io/npm/v/typescript-json.svg)](https://www.npmjs.com/package/typescript-json)
Expand All @@ -14,15 +14,23 @@ Super-fast Runtime type checker and `JSON.stringify()` functions, with only one
```typescript
import TSON from "typescript-json";

// RUNTIME TYPE CHECKERS
//----
// RUNTIME VALIDATORS
//----
// ALLOW SUPERFLUOUS PROPERTIES
TSON.assertType<T>(input); // throws exception
TSON.is<T>(input); // returns boolean value
TSON.validate<T>(input); // archives all type errors
TSON.validate<T>(input); // archives all errors

// STRINGIFY
TSON.stringify<T>(input); // 5x faster JSON.stringify()
// DO NOT ALLOW SUPERFLUOUS PROPERTIES
TSON.equals<T>(input); // returns boolean value
TSON.assertEquals<T>(input); // throws exception
TSON.validateEquals<T>(input); // archives all errors

//----
// APPENDIX FUNCTIONS
//----
TSON.stringify<T>(input); // 5x faster JSON.stringify()
TSON.application<[T, U, V], "swagger">(); // JSON schema application generator
TSON.create<T>(input); // 2x faster object creator (only one-time construction)
```
Expand Down Expand Up @@ -127,12 +135,18 @@ module.exports = {


## Features
### Runtime Type Checkers
### Runtime Validators
```typescript
export function assertType<T>(input: T): T; // throws `TypeGuardError`
// ALLOW SUPERFLUOUS PROPERTIES
export function is<T>(input: T): boolean; // true or false
export function assertType<T>(input: T): T; // throws `TypeGuardError`
export function validate<T>(input: T): IValidation; // detailed reasons

// DO NOT ALLOW SUPERFLUOUS PROPERTIES
export function equals<T>(input: T): boolean;
export function assertEquals<T>(input: T): T;
export function validateEquals<T>(input: T): IValidation;

export interface IValidation {
success: boolean;
errors: IValidation.IError[];
Expand All @@ -155,10 +169,34 @@ export class TypeGuardError extends Error {

> You can enhance type constraint more by using [**Comment Tags**](#comment-tags).
`typescript-json` provides three runtime type checker functions.
`typescript-json` provides three basic validator functions.

The first, `assertType()` is a function throwing `TypeGuardError` when an `input` value is different with its type, generic argument `T`. The second function, `is()` returns a `boolean` value meaning whether matched or not. The last `validate()` function archives all type errors into an `IValidation.errors` array.

If you want much strict validators that do not allow superfluous properties, you can use below functions instead. `assertEquals()` function throws `TypeGuardError`, `equals()` function returns `boolean` value, and `validateEquals()` function archives all type errors into an `IValidation.errors` array.

Basic | Strict
------|--------
`assertType` | `assertEquals`
`is` | `equals`
`validate` | `validateEquals`

```typescript
interface IPerson {
name: string;
age: number;
}

const person = {
name: "Jeongho Nam",
age: 34,
account: "samchon", // superfluous property
};

TSON.is<IPerson>(person); // -> true, allow superfluous property
TSON.equals<IPerson>(person); // -> false, do not allow
```

Comparing those type checker functions with other similar libraries, `typescript-json` is much easier than others, except only `typescript-is`. For example, `ajv` requires complicate JSON schema definition that is different with the TypeScript type. Besides, `typescript-json` requires only one line.

Also, only `typescript-json` can validate union typed structure exactly. All the other libraries can check simple object type, however, none of them can validate complicate union type. The fun thing is, `ajv` requires JSON schema definition for validation, but it can't validate the JSON schema type. How contradict it is.
Expand Down Expand Up @@ -229,7 +267,7 @@ When you need to share your TypeScript types to other language, this `applicatio
By the way, the reason why you're using this `application()` is for generating a swagger documents, I recommend you to use my another library [nestia](https://github.com/samchon/nestia). It will automate the swagger documents generation, by analyzing your entire backend server code.

### Comment Tags
You can enhance [Runtime Type Checkers](#runtime-type-checkers) and [JSON Schema Generator](#json-schema-generation) by writing comment tags.
You can enhance [Runtime Validators](#runtime-validators) and [JSON Schema Generator](#json-schema-generation) by writing comment tags.

Below table shows list of supported comment tags. You can utilize those tags by writing in comments like below example structure `TagExample`. Look at them and utilize those comment tags to make your TypeScript program to be safer and more convenient.

Expand Down
11 changes: 8 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "typescript-json",
"version": "3.2.5",
"version": "3.2.6",
"description": "Runtime type checkers and 5x faster JSON.stringify() function",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand All @@ -9,6 +9,7 @@
"build": "rimraf lib && ttsc --removeComments --declaration false && ttsc --emitDeclarationOnly",
"build:test": "rimraf bin && ttsc -p tsconfig.test.json && prettier --write ./bin/**/*.js",
"dev": "npm run build -- --watch",
"dev:test": "rimraf bin && ttsc -p tsconfig.test.json --watch",
"eslint": "eslint ./**/*.ts",
"eslint:fix": "eslint ./**/*.ts --fix",
"issue": "node test/issue",
Expand All @@ -32,10 +33,14 @@
"schema",
"jsonschema",
"generator",
"validator",
"assert",
"is",
"validate",
"equal",
"runtime",
"type",
"checker"
"checker",
"validator"
],
"author": "Jeongho Nam",
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions src/TypeGuardError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export class TypeGuardError extends Error {
this.method = props.method;
this.path = props.path;
this.expected = props.expected;
this.value = props.value;
}
}
export namespace TypeGuardError {
Expand Down
9 changes: 9 additions & 0 deletions src/factories/IdentifierFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,13 @@ export namespace IdentifierFactory {
? `".${str}"`
: `"[${JSON.stringify(str).split('"').join('\\"')}]"`;
}

export function parameter(name: string | ts.BindingName) {
return ts.factory.createParameterDeclaration(
undefined,
undefined,
undefined,
name,
);
}
}
50 changes: 50 additions & 0 deletions src/functional/$join.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
export function $join(str: string): string {
return variable(str) ? `.${str}` : `[${JSON.stringify(str)}]`;
}

function variable(str: string): boolean {
return reserved(str) === false && /^[a-zA-Z_$][a-zA-Z_$0-9]*$/g.test(str);
}

function reserved(str: string): boolean {
return RESERVED.has(str);
}

const RESERVED: Set<string> = new Set([
"break",
"case",
"catch",
"class",
"const",
"continue",
"debugger",
"default",
"delete",
"do",
"else",
"enum",
"export",
"extends",
"false",
"finally",
"for",
"function",
"if",
"import",
"in",
"instanceof",
"new",
"null",
"return",
"super",
"switch",
"this",
"throw",
"true",
"try",
"typeof",
"var",
"void",
"while",
"with",
]);
Loading

0 comments on commit fccd66e

Please sign in to comment.