typebox 1.1.12 → 1.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ import { type TUnion } from '../../types/union.mjs';
3
3
  import { type TDeferred } from '../../types/deferred.mjs';
4
4
  import { type TRef } from '../../types/ref.mjs';
5
5
  import { type TParameter } from '../../types/parameter.mjs';
6
- type TCollectDistributionNames<Expression extends TSchema, Result extends string[] = []> = (Expression extends TDeferred<'Conditional', [infer Left extends TSchema, infer _Right extends TSchema, infer True extends TSchema, infer False extends TSchema]> ? Left extends TRef<infer Name extends string> ? TCollectDistributionNames<True, TCollectDistributionNames<False, [...Result, Name]>> : TCollectDistributionNames<True, TCollectDistributionNames<False, Result>> : Expression extends TDeferred<'Mapped', [infer _Identifier extends TSchema, infer Type extends TSchema, infer _As extends TSchema, infer _Property extends TSchema]> ? (Type extends TDeferred<'KeyOf', [infer Ref extends TRef]> ? [...Result, Ref['$ref']] : Result) : Result);
6
+ type TCollectDistributionNames<Expression extends TSchema, Result extends string[] = []> = (Expression extends TDeferred<'Conditional', [infer Left extends TSchema, infer _Right extends TSchema, infer True extends TSchema, infer False extends TSchema]> ? Left extends TRef ? TCollectDistributionNames<True, TCollectDistributionNames<False, [...Result, Left['$ref']]>> : TCollectDistributionNames<True, TCollectDistributionNames<False, Result>> : Expression extends TDeferred<'Mapped', [infer _Identifier extends TSchema, infer Type extends TSchema, infer _As extends TSchema, infer _Property extends TSchema]> ? (Type extends TDeferred<'KeyOf', [infer Ref extends TRef]> ? [...Result, Ref['$ref']] : Result) : Result);
7
7
  type TBuildDistributionArray<Parameters extends TParameter[], Names extends string[], Result extends boolean[] = []> = (Parameters extends [infer Left extends TParameter, ...infer Right extends TParameter[]] ? Left['name'] extends Names[number] ? TBuildDistributionArray<Right, Names, [...Result, true]> : TBuildDistributionArray<Right, Names, [...Result, false]> : Result);
8
8
  type TZipDistributionArray<Arguments extends TSchema[], DistributionArray extends boolean[], Result extends [boolean, TSchema][] = []> = (Arguments extends [infer ArgumentLeft extends TSchema, ...infer ArgumentRight extends TSchema[]] ? DistributionArray extends [infer BooleanLeft extends boolean, ...infer BooleanRight extends boolean[]] ? TZipDistributionArray<ArgumentRight, BooleanRight, [...Result, [BooleanLeft, ArgumentLeft]]> : Result : Result);
9
9
  type TExpand<Type extends TSchema> = (Type extends TUnion<infer Types extends TSchema[]> ? [...Types] : [Type]);
@@ -8,7 +8,7 @@ function CollectDistributionNames(expression, result = []) {
8
8
  // Conditional
9
9
  IsDeferred(expression) && Guard.IsEqual(expression.action, 'Conditional')
10
10
  ? IsRef(expression.parameters[0])
11
- ? CollectDistributionNames(expression.parameters[2], CollectDistributionNames(expression.parameters[3], [...result, expression.parameters[0].$ref]))
11
+ ? CollectDistributionNames(expression.parameters[2], CollectDistributionNames(expression.parameters[3], [...result, expression.parameters[0]['$ref']]))
12
12
  : CollectDistributionNames(expression.parameters[2], CollectDistributionNames(expression.parameters[3], result))
13
13
  // Mapped
14
14
  : IsDeferred(expression) && Guard.IsEqual(expression.action, 'Mapped')
@@ -1,8 +1,10 @@
1
1
  import { type TSchema } from '../types/schema.mjs';
2
2
  import { type TProperties } from '../types/properties.mjs';
3
+ import { type TAny } from '../types/any.mjs';
3
4
  import { type TConstructor } from '../types/constructor.mjs';
5
+ import { type TUnknown } from '../types/unknown.mjs';
4
6
  import * as Result from './result.mjs';
5
7
  import { type TExtendsParameters } from './parameters.mjs';
6
8
  import { type TExtendsReturnType } from './return-type.mjs';
7
- export type TExtendsConstructor<Inferred extends TProperties, Parameters extends TSchema[], InstanceType extends TSchema, Right extends TSchema> = (Right extends TConstructor<infer RightParamters extends TSchema[], infer RightInstanceType extends TSchema> ? TExtendsParameters<Inferred, Parameters, RightParamters> extends Result.TExtendsTrueLike<infer Inferred extends TProperties> ? TExtendsReturnType<Inferred, InstanceType, RightInstanceType> : Result.TExtendsFalse : Result.TExtendsFalse);
9
+ export type TExtendsConstructor<Inferred extends TProperties, Parameters extends TSchema[], InstanceType extends TSchema, Right extends TSchema> = (Right extends TAny ? Result.TExtendsTrue<Inferred> : Right extends TUnknown ? Result.TExtendsTrue<Inferred> : Right extends TConstructor ? TExtendsParameters<Inferred, Parameters, Right['parameters']> extends Result.TExtendsTrueLike<infer Inferred extends TProperties> ? TExtendsReturnType<Inferred, InstanceType, Right['instanceType']> : Result.TExtendsFalse : Result.TExtendsFalse);
8
10
  export declare function ExtendsConstructor<Inferred extends TProperties, Parameters extends TSchema[], InstanceType extends TSchema, Right extends TSchema>(inferred: Inferred, parameters: [...Parameters], returnType: InstanceType, right: Right): TExtendsConstructor<Inferred, Parameters, InstanceType, Right>;
@@ -1,5 +1,7 @@
1
1
  // deno-fmt-ignore-file
2
+ import { IsAny } from '../types/any.mjs';
2
3
  import { IsConstructor } from '../types/constructor.mjs';
4
+ import { IsUnknown } from '../types/unknown.mjs';
3
5
  import * as Result from './result.mjs';
4
6
  // ------------------------------------------------------------------
5
7
  // Parameters | ReturnType
@@ -7,10 +9,9 @@ import * as Result from './result.mjs';
7
9
  import { ExtendsParameters } from './parameters.mjs';
8
10
  import { ExtendsReturnType } from './return-type.mjs';
9
11
  export function ExtendsConstructor(inferred, parameters, returnType, right) {
10
- return (IsConstructor(right) ? (() => {
11
- const check = ExtendsParameters(inferred, parameters, right.parameters);
12
- return Result.IsExtendsTrueLike(check)
13
- ? ExtendsReturnType(check.inferred, returnType, right.instanceType)
14
- : Result.ExtendsFalse();
15
- })() : Result.ExtendsFalse());
12
+ return (IsAny(right) ? Result.ExtendsTrue(inferred) :
13
+ IsUnknown(right) ? Result.ExtendsTrue(inferred) :
14
+ IsConstructor(right) ? Result.Match(ExtendsParameters(inferred, parameters, right['parameters']), inferred => ExtendsReturnType(inferred, returnType, right['instanceType']), () => Result.ExtendsFalse()) // 'not-a-parameter-match'
15
+ : Result.ExtendsFalse() // 'not-a-constructor'
16
+ );
16
17
  }
@@ -1,6 +1,5 @@
1
1
  // deno-fmt-ignore-file
2
2
  import { Memory } from '../../system/memory/index.mjs';
3
- import { IsSchema } from '../types/schema.mjs';
4
3
  import { IsAny } from '../types/any.mjs';
5
4
  import { IsEnum } from '../types/enum.mjs';
6
5
  import { IsInfer } from '../types/infer.mjs';
@@ -13,10 +12,7 @@ import * as Result from './result.mjs';
13
12
  import { TemplateLiteralDecode } from '../engine/template-literal/decode.mjs';
14
13
  import { EnumValuesToUnion } from '../engine/enum/index.mjs';
15
14
  function ExtendsRightInfer(inferred, name, left, right) {
16
- const check = ExtendsLeft(inferred, left, right);
17
- return (Result.IsExtendsTrueLike(check)
18
- ? Result.ExtendsTrue(Memory.Assign(Memory.Assign(inferred, check.inferred), { [name]: left }))
19
- : Result.ExtendsFalse());
15
+ return Result.Match(ExtendsLeft(inferred, left, right), checkInferred => Result.ExtendsTrue(Memory.Assign(Memory.Assign(inferred, checkInferred), { [name]: left })), () => Result.ExtendsFalse());
20
16
  }
21
17
  function ExtendsRightAny(inferred, left) {
22
18
  return Result.ExtendsTrue(inferred);
@@ -26,26 +22,14 @@ function ExtendsRightEnum(inferred, left, right) {
26
22
  return ExtendsLeft(inferred, left, union);
27
23
  }
28
24
  function ExtendsRightIntersect(inferred, left, right) {
29
- const [head, ...tail] = right;
30
- return (IsSchema(head) ? (() => {
31
- const check = ExtendsLeft(inferred, left, head);
32
- return Result.IsExtendsTrueLike(check)
33
- ? ExtendsRightIntersect(check.inferred, left, tail)
34
- : Result.ExtendsFalse();
35
- })() : Result.ExtendsTrue(inferred));
25
+ return Result.TakeLeft(right, (head, tail) => Result.Match(ExtendsLeft(inferred, left, head), inferred => ExtendsRightIntersect(inferred, left, tail), () => Result.ExtendsFalse()), () => Result.ExtendsTrue(inferred));
36
26
  }
37
27
  function ExtendsRightTemplateLiteral(inferred, left, right) {
38
28
  const decoded = TemplateLiteralDecode(right);
39
29
  return ExtendsLeft(inferred, left, decoded);
40
30
  }
41
31
  function ExtendsRightUnion(inferred, left, right) {
42
- const [head, ...tail] = right;
43
- return (IsSchema(head) ? (() => {
44
- const check = ExtendsLeft(inferred, left, head);
45
- return Result.IsExtendsTrueLike(check)
46
- ? Result.ExtendsTrue(check.inferred)
47
- : ExtendsRightUnion(inferred, left, tail);
48
- })() : Result.ExtendsFalse());
32
+ return Result.TakeLeft(right, (head, tail) => Result.Match(ExtendsLeft(inferred, left, head), inferred => Result.ExtendsTrue(inferred), () => ExtendsRightUnion(inferred, left, tail)), () => Result.ExtendsFalse());
49
33
  }
50
34
  export function ExtendsRight(inferred, left, right) {
51
35
  return (IsAny(right) ? ExtendsRightAny(inferred, left) :
@@ -1,8 +1,10 @@
1
1
  import { type TSchema } from '../types/schema.mjs';
2
2
  import { type TProperties } from '../types/properties.mjs';
3
+ import { type TAny } from '../types/any.mjs';
3
4
  import { type TFunction } from '../types/function.mjs';
5
+ import { type TUnknown } from '../types/unknown.mjs';
4
6
  import * as Result from './result.mjs';
5
7
  import { type TExtendsParameters } from './parameters.mjs';
6
8
  import { type TExtendsReturnType } from './return-type.mjs';
7
- export type TExtendsFunction<Inferred extends TProperties, Parameters extends TSchema[], ReturnType extends TSchema, Right extends TSchema> = (Right extends TFunction<infer RightParamters extends TSchema[], infer RightReturnType extends TSchema> ? TExtendsParameters<Inferred, Parameters, RightParamters> extends Result.TExtendsTrueLike<infer Inferred extends TProperties> ? TExtendsReturnType<Inferred, ReturnType, RightReturnType> : Result.TExtendsFalse : Result.TExtendsFalse);
9
+ export type TExtendsFunction<Inferred extends TProperties, Parameters extends TSchema[], ReturnType extends TSchema, Right extends TSchema> = (Right extends TAny ? Result.TExtendsTrue<Inferred> : Right extends TUnknown ? Result.TExtendsTrue<Inferred> : Right extends TFunction ? TExtendsParameters<Inferred, Parameters, Right['parameters']> extends Result.TExtendsTrueLike<infer Inferred extends TProperties> ? TExtendsReturnType<Inferred, ReturnType, Right['returnType']> : Result.TExtendsFalse : Result.TExtendsFalse);
8
10
  export declare function ExtendsFunction<Inferred extends TProperties, Parameters extends TSchema[], ReturnType extends TSchema, Right extends TSchema>(inferred: Inferred, parameters: [...Parameters], returnType: ReturnType, right: Right): TExtendsFunction<Inferred, Parameters, ReturnType, Right>;
@@ -1,5 +1,7 @@
1
1
  // deno-fmt-ignore-file
2
+ import { IsAny } from '../types/any.mjs';
2
3
  import { IsFunction } from '../types/function.mjs';
4
+ import { IsUnknown } from '../types/unknown.mjs';
3
5
  import * as Result from './result.mjs';
4
6
  // ------------------------------------------------------------------
5
7
  // Parameters | ReturnType
@@ -7,10 +9,9 @@ import * as Result from './result.mjs';
7
9
  import { ExtendsParameters } from './parameters.mjs';
8
10
  import { ExtendsReturnType } from './return-type.mjs';
9
11
  export function ExtendsFunction(inferred, parameters, returnType, right) {
10
- return (IsFunction(right) ? (() => {
11
- const check = ExtendsParameters(inferred, parameters, right.parameters);
12
- return Result.IsExtendsTrueLike(check)
13
- ? ExtendsReturnType(check.inferred, returnType, right.returnType)
14
- : Result.ExtendsFalse();
15
- })() : Result.ExtendsFalse());
12
+ return (IsAny(right) ? Result.ExtendsTrue(inferred) :
13
+ IsUnknown(right) ? Result.ExtendsTrue(inferred) :
14
+ IsFunction(right) ? Result.Match(ExtendsParameters(inferred, parameters, right['parameters']), inferred => ExtendsReturnType(inferred, returnType, right['returnType']), () => Result.ExtendsFalse()) // 'not-a-parameter-match'
15
+ : Result.ExtendsFalse() // 'not-a-function'
16
+ );
16
17
  }
@@ -21,7 +21,7 @@ export type TTryRestInferable<Type extends TSchema, Result extends TInferable |
21
21
  export declare function TryRestInferable<Type extends TSchema>(type: Type): TTryRestInferable<Type>;
22
22
  export type TTryInferable<Type extends TSchema, Result extends TInferable | undefined = (Type extends TInfer<infer Name extends string, infer Type extends TSchema> ? TInferable<Name, Type> : undefined)> = Result;
23
23
  export declare function TryInferable<Type extends TSchema>(type: Type): TTryInferable<Type>;
24
- type TryInferResults<Rest extends TSchema[], Right extends TSchema, Result extends TSchema[] = []> = (Rest extends [infer Head extends TSchema, ...infer Tail extends TSchema[]] ? TExtendsLeft<{}, Head, Right> extends Result.TExtendsTrueLike<TProperties> ? TryInferResults<Tail, Right, [...Result, Head]> : undefined : Result);
24
+ type TryInferResults<Rest extends TSchema[], Right extends TSchema, Result extends TSchema[] = []> = (Rest extends [infer Head extends TSchema, ...infer Tail extends TSchema[]] ? TExtendsLeft<{}, Head, Right> extends Result.TExtendsTrueLike ? TryInferResults<Tail, Right, [...Result, Head]> : undefined : Result);
25
25
  declare function TryInferResults<Rest extends TSchema[], Right extends TSchema>(rest: [...Rest], right: Right, result?: TSchema[]): TryInferResults<Rest, Right>;
26
26
  export type TInferTupleResult<Inferred extends TProperties, Name extends string, Left extends TSchema[], Right extends TSchema, Results extends TSchema[] | undefined = TryInferResults<Left, Right>> = (Results extends [...infer Results extends TSchema[]] ? Result.TExtendsTrue<Memory.TAssign<Inferred, {
27
27
  [_ in Name]: TTuple<Results>;
@@ -2,10 +2,6 @@
2
2
  import { Unreachable } from '../../system/unreachable/index.mjs';
3
3
  import { Memory } from '../../system/memory/index.mjs';
4
4
  import { Guard } from '../../guard/index.mjs';
5
- // ----------------------------------------------------------------------------
6
- // Schematics
7
- // ----------------------------------------------------------------------------
8
- import { IsSchema } from '../types/schema.mjs';
9
5
  import { IsArray } from '../types/array.mjs';
10
6
  import { IsUnknown } from '../types/unknown.mjs';
11
7
  import { Tuple } from '../types/tuple.mjs';
@@ -49,14 +45,7 @@ export function TryInferable(type) {
49
45
  undefined);
50
46
  }
51
47
  function TryInferResults(rest, right, result = []) {
52
- const [head, ...tail] = rest;
53
- return (IsSchema(head)
54
- ? (() => {
55
- const check = ExtendsLeft({}, head, right);
56
- return Result.IsExtendsTrueLike(check)
57
- ? TryInferResults(tail, right, [...result, head])
58
- : undefined;
59
- })() : result);
48
+ return Result.TakeLeft(rest, (head, tail) => Result.Match(ExtendsLeft({}, head, right), () => TryInferResults(tail, right, [...result, head]), () => undefined), () => result);
60
49
  }
61
50
  export function InferTupleResult(inferred, name, left, right) {
62
51
  const results = TryInferResults(left, right);
@@ -19,12 +19,9 @@ function ExtendsPropertyOptional(inferred, left, right) {
19
19
  function ExtendsProperty(inferred, left, right) {
20
20
  return (
21
21
  // Right TInfer<TNever> is TExtendsFalse
22
- IsInfer(right) && IsNever(right.extends) ? Result.ExtendsFalse() : (() => {
23
- const check = ExtendsLeft(inferred, left, right);
24
- return (Result.IsExtendsTrueLike(check)
25
- ? ExtendsPropertyOptional(check.inferred, left, right)
26
- : Result.ExtendsFalse());
27
- })());
22
+ (IsInfer(right) && IsNever(right.extends))
23
+ ? Result.ExtendsFalse()
24
+ : Result.Match(ExtendsLeft(inferred, left, right), inferred => ExtendsPropertyOptional(inferred, left, right), () => Result.ExtendsFalse()));
28
25
  }
29
26
  function ExtractInferredProperties(keys, properties) {
30
27
  return keys.reduce((result, key) => {
@@ -1,6 +1,5 @@
1
1
  // deno-fmt-ignore-file
2
2
  import { IsInfer } from '../types/infer.mjs';
3
- import { IsSchema } from '../types/schema.mjs';
4
3
  import { IsOptional } from '../types/_optional.mjs';
5
4
  import { ExtendsLeft } from './extends-left.mjs';
6
5
  import * as Result from './result.mjs';
@@ -10,27 +9,18 @@ function ParameterCompare(inferred, left, leftRest, right, rightRest) {
10
9
  const checkRight = IsInfer(right) ? right : left;
11
10
  const isLeftOptional = IsOptional(left);
12
11
  const isRightOptional = IsOptional(right);
13
- const check = ExtendsLeft(inferred, checkLeft, checkRight);
14
- return (!isLeftOptional && isRightOptional
15
- ? Result.ExtendsFalse()
16
- : Result.IsExtendsTrueLike(check)
17
- ? ExtendsParameters(check.inferred, leftRest, rightRest)
18
- : Result.ExtendsFalse());
12
+ return ((!isLeftOptional && isRightOptional)
13
+ ? Result.ExtendsFalse() // 'fail: left-required-but-right-is-optional'
14
+ : Result.Match(ExtendsLeft(inferred, checkLeft, checkRight), inferred => ExtendsParameters(inferred, leftRest, rightRest), () => Result.ExtendsFalse()) // 'fail: left-and-right-did-not-match'
15
+ );
19
16
  }
20
17
  function ParameterRight(inferred, left, leftRest, rightRest) {
21
- const [head, ...tail] = rightRest;
22
- return (IsSchema(head)
23
- ? ParameterCompare(inferred, left, leftRest, head, tail)
24
- : IsOptional(left) // 'right-did-not-have-enough-elements'
25
- ? Result.ExtendsTrue(inferred) // 'ok: left was optional'
26
- : Result.ExtendsFalse() // 'fail: left was required'
27
- );
18
+ return Result.TakeLeft(rightRest, (head, tail) => ParameterCompare(inferred, left, leftRest, head, tail), () => IsOptional(left) // 'right-did-not-have-enough-elements'
19
+ ? Result.ExtendsTrue(inferred) // 'ok: left was optional'
20
+ : Result.ExtendsFalse()); // 'fail: left was required'
28
21
  }
29
22
  function ParametersLeft(inferred, left, rightRest) {
30
- const [head, ...tail] = left;
31
- return (IsSchema(head)
32
- ? ParameterRight(inferred, head, tail, rightRest)
33
- : Result.ExtendsTrue(inferred));
23
+ return Result.TakeLeft(left, (head, tail) => ParameterRight(inferred, head, tail, rightRest), () => Result.ExtendsTrue(inferred)); // 'ok: no-more-elements-in-left'
34
24
  }
35
25
  export function ExtendsParameters(inferred, left, right) {
36
26
  return ParametersLeft(inferred, left, right);
@@ -19,3 +19,9 @@ export declare function ExtendsFalse(): TExtendsFalse;
19
19
  export declare function IsExtendsFalse(value: unknown): value is TExtendsFalse;
20
20
  export type TExtendsTrueLike<Inferred extends TProperties = TProperties> = TExtendsUnion<Inferred> | TExtendsTrue<Inferred>;
21
21
  export declare function IsExtendsTrueLike(value: unknown): value is TExtendsTrueLike;
22
+ export type MatchTrueLike = (inferred: TProperties) => unknown;
23
+ export type MatchFalse = () => unknown;
24
+ export declare function Match(result: TResult, true_: MatchTrueLike, false_: MatchFalse): unknown;
25
+ export type TakeLeftTrue<T> = (left: T, right: T[]) => unknown;
26
+ export type TakeLeftFalse = () => unknown;
27
+ export declare function TakeLeft<T>(array: T[], true_: TakeLeftTrue<T>, false_: TakeLeftFalse): unknown;
@@ -31,3 +31,9 @@ export function IsExtendsFalse(value) {
31
31
  export function IsExtendsTrueLike(value) {
32
32
  return IsExtendsUnion(value) || IsExtendsTrue(value);
33
33
  }
34
+ export function Match(result, true_, false_) {
35
+ return IsExtendsTrueLike(result) ? true_(result.inferred) : false_();
36
+ }
37
+ export function TakeLeft(array, true_, false_) {
38
+ return Guard.IsEqual(array.length, 0) ? false_() : true_(array[0], array.slice(1));
39
+ }
@@ -11,13 +11,13 @@ type TReverse<Types extends TSchema[], Result extends TSchema[] = []> = (Types e
11
11
  type TApplyReverse<Types extends TSchema[], Reversed extends boolean> = Reversed extends true ? TReverse<Types> : Types;
12
12
  type TReversed<Types extends TSchema[], First extends TSchema | undefined = Types extends [infer Left extends TSchema, ...infer _ extends TSchema[]] ? Left : undefined, Inferable extends TSchema | undefined = First extends TSchema ? TTryRestInferable<First> : undefined, Result extends boolean = Inferable extends TSchema ? true : false> = Result;
13
13
  type TElementsCompare<Inferred extends TProperties, Reversed extends boolean, Left extends TSchema, LeftRest extends TSchema[], Right extends TSchema, RightRest extends TSchema[]> = (TExtendsLeft<Inferred, Left, Right> extends Result.TExtendsTrueLike<infer CheckInferred extends TProperties> ? TElements<CheckInferred, Reversed, LeftRest, RightRest> : Result.TExtendsFalse);
14
- type TElementsLeft<Inferred extends TProperties, Reversed extends boolean, LeftRest extends TSchema[], Right extends TSchema, RightRest extends TSchema[], Inferable extends TInferable | undefined = TTryRestInferable<Right>> = (Inferable extends TInferable<infer Name extends string, infer Type extends TSchema> ? TInferTupleResult<Inferred, Name, TApplyReverse<LeftRest, Reversed>, Type> : LeftRest extends [infer Head extends TSchema, ...infer Tail extends TSchema[]] ? TElementsCompare<Inferred, Reversed, Head, Tail, Right, RightRest> : Result.TExtendsFalse);
14
+ type TElementsLeft<Inferred extends TProperties, Reversed extends boolean, LeftRest extends TSchema[], Right extends TSchema, RightRest extends TSchema[], Inferable extends TInferable | undefined = TTryRestInferable<Right>> = (Inferable extends TInferable ? TInferTupleResult<Inferred, Inferable['name'], TApplyReverse<LeftRest, Reversed>, Inferable['type']> : LeftRest extends [infer Head extends TSchema, ...infer Tail extends TSchema[]] ? TElementsCompare<Inferred, Reversed, Head, Tail, Right, RightRest> : Result.TExtendsFalse);
15
15
  type TElementsRight<Inferred extends TProperties, Reversed extends boolean, LeftRest extends TSchema[], RightRest extends TSchema[]> = (RightRest extends [infer Head extends TSchema, ...infer Tail extends TSchema[]] ? TElementsLeft<Inferred, Reversed, LeftRest, Head, Tail> : LeftRest['length'] extends 0 ? Result.TExtendsTrue<Inferred> : Result.TExtendsFalse);
16
16
  type TElements<Inferred extends TProperties, Reversed extends boolean, LeftRest extends TSchema[], RightRest extends TSchema[]> = TElementsRight<Inferred, Reversed, LeftRest, RightRest>;
17
17
  type TExtendsTupleToTuple<Inferred extends TProperties, Left extends TSchema[], Right extends TSchema[], InstantiatedRight extends TSchema[] = TInstantiateElements<Inferred, {
18
18
  callstack: [];
19
19
  }, Right>, Reversed extends boolean = TReversed<InstantiatedRight>> = TElements<Inferred, Reversed, TApplyReverse<Left, Reversed>, TApplyReverse<InstantiatedRight, Reversed>>;
20
- type TExtendsTupleToArray<Inferred extends TProperties, Left extends TSchema[], Right extends TSchema, Inferrable extends TInferable | undefined = TTryInferable<Right>> = (Inferrable extends TInferable<infer Name extends string, infer Type extends TSchema> ? TInferUnionResult<Inferred, Name, Left, Type> : Left extends [infer Head extends TSchema, ...infer Tail extends TSchema[]] ? TExtendsLeft<Inferred, Head, Right> extends Result.TExtendsTrueLike<infer Inferred extends TProperties> ? TExtendsTupleToArray<Inferred, Tail, Right> : Result.TExtendsFalse : Result.TExtendsTrue<Inferred>);
20
+ type TExtendsTupleToArray<Inferred extends TProperties, Left extends TSchema[], Right extends TSchema, Inferrable extends TInferable | undefined = TTryInferable<Right>> = (Inferrable extends TInferable ? TInferUnionResult<Inferred, Inferrable['name'], Left, Inferrable['type']> : Left extends [infer Head extends TSchema, ...infer Tail extends TSchema[]] ? TExtendsLeft<Inferred, Head, Right> extends Result.TExtendsTrueLike<infer Inferred extends TProperties> ? TExtendsTupleToArray<Inferred, Tail, Right> : Result.TExtendsFalse : Result.TExtendsTrue<Inferred>);
21
21
  export type TExtendsTuple<Inferred extends TProperties, Left extends TSchema[], Right extends TSchema, InstantiatedLeft extends TSchema[] = TInstantiateElements<Inferred, {
22
22
  callstack: [];
23
23
  }, Left>> = (Right extends TTuple<infer Types extends TSchema[]> ? TExtendsTupleToTuple<Inferred, InstantiatedLeft, Types> : Right extends TArray<infer Type extends TSchema> ? TExtendsTupleToArray<Inferred, InstantiatedLeft, Type> : TExtendsRight<Inferred, TTuple<InstantiatedLeft>, Right>);
@@ -23,31 +23,20 @@ function Reversed(types) {
23
23
  return IsSchema(inferrable);
24
24
  }
25
25
  function ElementsCompare(inferred, reversed, left, leftRest, right, rightRest) {
26
- const check = ExtendsLeft(inferred, left, right);
27
- return (Result.IsExtendsTrueLike(check)
28
- ? Elements(check.inferred, reversed, leftRest, rightRest)
29
- : Result.ExtendsFalse() // 'left-and-right-not-compared'
30
- );
26
+ return Result.Match(ExtendsLeft(inferred, left, right), checkInferred => Elements(checkInferred, reversed, leftRest, rightRest), () => Result.ExtendsFalse()); // 'left-and-right-not-compared'
31
27
  }
32
28
  function ElementsLeft(inferred, reversed, leftRest, right, rightRest) {
33
29
  const inferable = TryRestInferable(right);
34
- return (IsInferable(inferable)
35
- ? InferTupleResult(inferred, inferable.name, ApplyReverse(leftRest, reversed), inferable.type)
36
- : (() => {
37
- const [head, ...tail] = leftRest;
38
- return IsSchema(head)
39
- ? ElementsCompare(inferred, reversed, head, tail, right, rightRest)
40
- : Result.ExtendsFalse();
41
- })());
30
+ return (
31
+ // Rest Inferrable Right Means we delegate to TInferTupleResult to Generate a Result
32
+ IsInferable(inferable)
33
+ ? InferTupleResult(inferred, inferable['name'], ApplyReverse(leftRest, reversed), inferable['type'])
34
+ : Result.TakeLeft(leftRest, (head, tail) => ElementsCompare(inferred, reversed, head, tail, right, rightRest), () => Result.ExtendsFalse()));
42
35
  }
43
36
  function ElementsRight(inferred, reversed, leftRest, rightRest) {
44
- const [head, ...tail] = rightRest;
45
- return (IsSchema(head)
46
- ? ElementsLeft(inferred, reversed, leftRest, head, tail)
47
- : Guard.IsEqual(leftRest.length, 0)
48
- ? Result.ExtendsTrue(inferred) // 'Ok: right-empty-and-left-empty'
49
- : Result.ExtendsFalse() // 'Fail: right-empty-and-left-not-empty'
50
- );
37
+ return Result.TakeLeft(rightRest, (head, tail) => ElementsLeft(inferred, reversed, leftRest, head, tail), () => Guard.IsEqual(leftRest.length, 0)
38
+ ? Result.ExtendsTrue(inferred) // 'Ok: right-empty-and-left-empty'
39
+ : Result.ExtendsFalse()); // 'Fail: right-empty-and-left-not-empty'
51
40
  }
52
41
  function Elements(inferred, reversed, leftRest, rightRest) {
53
42
  return ElementsRight(inferred, reversed, leftRest, rightRest);
@@ -60,19 +49,8 @@ function ExtendsTupleToTuple(inferred, left, right) {
60
49
  function ExtendsTupleToArray(inferred, left, right) {
61
50
  const inferrable = TryInferable(right);
62
51
  return (IsInferable(inferrable)
63
- // @ts-ignore 4.9.5 fails to see `type` property on inferrable
64
- ? InferUnionResult(inferred, inferrable.name, left, inferrable.type)
65
- : (() => {
66
- const [head, ...tail] = left;
67
- return IsSchema(head)
68
- ? (() => {
69
- const check = ExtendsLeft(inferred, head, right);
70
- return Result.IsExtendsTrueLike(check)
71
- ? ExtendsTupleToArray(check.inferred, tail, right)
72
- : Result.ExtendsFalse();
73
- })()
74
- : Result.ExtendsTrue(inferred);
75
- })());
52
+ ? InferUnionResult(inferred, inferrable['name'], left, inferrable['type'])
53
+ : Result.TakeLeft(left, (head, tail) => Result.Match(ExtendsLeft(inferred, head, right), inferred => ExtendsTupleToArray(inferred, tail, right), () => Result.ExtendsFalse()), () => Result.ExtendsTrue(inferred)));
76
54
  }
77
55
  export function ExtendsTuple(inferred, left, right) {
78
56
  const instantiatedLeft = InstantiateElements(inferred, { callstack: [] }, left);
@@ -1,5 +1,4 @@
1
1
  // deno-fmt-ignore-file
2
- import { IsSchema } from '../types/schema.mjs';
3
2
  import { IsUnion } from '../types/union.mjs';
4
3
  import { ExtendsLeft } from './extends-left.mjs';
5
4
  import * as Result from './result.mjs';
@@ -8,22 +7,10 @@ import * as Result from './result.mjs';
8
7
  // ----------------------------------------------------------------------------
9
8
  import { IsInferable, TryInferable, InferUnionResult } from './inference.mjs';
10
9
  function ExtendsUnionSome(inferred, type, unionTypes) {
11
- const [head, ...tail] = unionTypes;
12
- return (IsSchema(head) ? (() => {
13
- const check = ExtendsLeft(inferred, type, head);
14
- return Result.IsExtendsTrueLike(check)
15
- ? Result.ExtendsTrue(check.inferred)
16
- : ExtendsUnionSome(inferred, type, tail);
17
- })() : Result.ExtendsFalse());
10
+ return Result.TakeLeft(unionTypes, (head, tail) => Result.Match(ExtendsLeft(inferred, type, head), inferred => Result.ExtendsTrue(inferred), () => ExtendsUnionSome(inferred, type, tail)), () => Result.ExtendsFalse());
18
11
  }
19
12
  function ExtendsUnionLeft(inferred, left, right) {
20
- const [head, ...tail] = left;
21
- return (IsSchema(head) ? (() => {
22
- const check = ExtendsUnionSome(inferred, head, right);
23
- return Result.IsExtendsTrueLike(check)
24
- ? ExtendsUnionLeft(check.inferred, tail, right)
25
- : Result.ExtendsFalse();
26
- })() : Result.ExtendsTrue(inferred));
13
+ return Result.TakeLeft(left, (head, tail) => Result.Match(ExtendsUnionSome(inferred, head, right), inferred => ExtendsUnionLeft(inferred, tail, right), () => Result.ExtendsFalse()), () => Result.ExtendsTrue(inferred));
27
14
  }
28
15
  export function ExtendsUnion(inferred, left, right) {
29
16
  const inferrable = TryInferable(right);
@@ -164,7 +164,7 @@ export type TExtendsMapping<Input extends [unknown, unknown, unknown, unknown, u
164
164
  export declare function ExtendsMapping(input: [unknown, unknown, unknown, unknown, unknown, unknown] | []): unknown;
165
165
  export type TBaseMapping<Input extends [unknown, unknown, unknown] | unknown> = (Input extends ['(', infer Type extends T.TSchema, ')'] ? Type : Input extends infer Type extends T.TSchema ? Type : never);
166
166
  export declare function BaseMapping(input: [unknown, unknown, unknown] | unknown): unknown;
167
- type TFactorIndexArray<Type extends T.TSchema, IndexArray extends unknown[]> = (IndexArray extends [...infer Left extends unknown[], infer Right extends T.TSchema[]] ? (Right extends [infer Indexer extends T.TSchema] ? C.TIndexDeferred<TFactorIndexArray<Type, Left>, Indexer> : Right extends [] ? T.TArray<TFactorIndexArray<Type, Left>> : T.TNever) : Type);
167
+ type TFactorIndexArray<Type extends T.TSchema, IndexArray extends unknown[]> = (IndexArray extends [infer Left extends T.TSchema[], ...infer Right extends unknown[]] ? (Left extends [infer Indexer extends T.TSchema] ? TFactorIndexArray<C.TIndexDeferred<Type, Indexer>, Right> : Left extends [] ? TFactorIndexArray<T.TArray<Type>, Right> : T.TNever) : Type);
168
168
  type TFactorExtends<Type extends T.TSchema, Extends extends unknown[]> = (Extends extends [infer Right extends T.TSchema, infer True extends T.TSchema, infer False extends T.TSchema] ? C.TConditionalDeferred<Type, Right, True, False> : Type);
169
169
  export type TFactorMapping<Input extends [unknown, unknown, unknown, unknown]> = (Input extends [infer KeyOf extends boolean, infer Type extends T.TSchema, infer IndexArray extends unknown[], infer Extend extends unknown[]] ? KeyOf extends true ? TFactorExtends<C.TKeyOfDeferred<TFactorIndexArray<Type, IndexArray>>, Extend> : TFactorExtends<TFactorIndexArray<Type, IndexArray>, Extend> : never);
170
170
  export declare function FactorMapping(input: [unknown, unknown, unknown, unknown]): unknown;
@@ -188,10 +188,10 @@ export function BaseMapping(input) {
188
188
  // deno-coverage-ignore-start
189
189
  // ...
190
190
  const FactorIndexArray = (Type, indexArray) => {
191
- return indexArray.reduceRight((result, right) => {
192
- const _right = right;
193
- return (Guard.IsEqual(_right.length, 1) ? C.IndexDeferred(result, _right[0]) :
194
- Guard.IsEqual(_right.length, 0) ? T.Array(result) :
191
+ return indexArray.reduce((result, left) => {
192
+ const _left = left;
193
+ return (Guard.IsEqual(_left.length, 1) ? C.IndexDeferred(result, _left[0]) :
194
+ Guard.IsEqual(_left.length, 0) ? T.Array(result) :
195
195
  Unreachable());
196
196
  }, Type);
197
197
  };
@@ -2,9 +2,30 @@
2
2
  import { Guard } from '../../guard/index.mjs';
3
3
  import { FromType } from './from-type.mjs';
4
4
  import { Callback } from './callback.mjs';
5
- export function FromRef(direction, context, type, value) {
6
- value = Guard.HasPropertyKey(context, type.$ref)
5
+ // ------------------------------------------------------------------
6
+ // ResolveRef
7
+ // ------------------------------------------------------------------
8
+ function ResolveRef(direction, context, type, value) {
9
+ return Guard.HasPropertyKey(context, type.$ref)
7
10
  ? FromType(direction, context, context[type.$ref], value)
8
11
  : value;
9
- return Callback(direction, context, type, value);
12
+ }
13
+ // ------------------------------------------------------------------
14
+ // FromRef
15
+ //
16
+ // Decode and Encode apply the Callback and the referenced type's
17
+ // codec pipeline in opposite orders, since the two operations are
18
+ // inverses of each other.
19
+ //
20
+ // Decode: referenced type resolves first, Callback runs after.
21
+ // wire value -> resolve $ref -> Callback -> decoded value
22
+ //
23
+ // Encode: Callback runs first, referenced type resolves after.
24
+ // encoded value -> Callback -> resolve $ref -> wire value
25
+ //
26
+ // ------------------------------------------------------------------
27
+ export function FromRef(direction, context, type, value) {
28
+ return Guard.IsEqual(direction, 'Decode')
29
+ ? Callback(direction, context, type, ResolveRef(direction, context, type, value))
30
+ : ResolveRef(direction, context, type, Callback(direction, context, type, value));
10
31
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "typebox",
3
3
  "description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
4
- "version": "1.1.12",
4
+ "version": "1.1.14",
5
5
  "keywords": [
6
6
  "typescript",
7
7
  "jsonschema"
package/readme.md CHANGED
@@ -28,21 +28,21 @@ $ npm install typebox
28
28
  ```typescript
29
29
  import Type from 'typebox'
30
30
 
31
- const T = Type.Object({ // const T = {
32
- x: Type.Number(), // type: 'object',
33
- y: Type.Number(), // required: ['x', 'y', 'z'],
34
- z: Type.Number() // properties: {
35
- }) // x: { type: 'number' },
36
- // y: { type: 'number' },
37
- // z: { type: 'number' }
38
- // }
39
- // }
40
-
41
- type T = Type.Static<typeof T> // type T = {
42
- // x: number,
43
- // y: number,
44
- // z: number
45
- // }
31
+ const T = Type.Object({ // const T = {
32
+ x: Type.Number(), // type: 'object',
33
+ y: Type.Number(), // properties: {
34
+ z: Type.Number() // x: { type: 'number' },
35
+ }) // y: { type: 'number' },
36
+ // z: { type: 'number' }
37
+ // },
38
+ // required: ['x', 'y', 'z']
39
+ // }
40
+
41
+ type T = Type.Static<typeof T> // type T = {
42
+ // x: number,
43
+ // y: number,
44
+ // z: number
45
+ // }
46
46
  ```
47
47
 
48
48
  ## Overview
@@ -58,7 +58,6 @@ License: MIT
58
58
  ## Contents
59
59
 
60
60
  - [Type](#Type)
61
- - [Value](#Value)
62
61
  - [Script](#Script)
63
62
  - [Schema](#Schema)
64
63
  - [Versions](#Versions)
@@ -69,157 +68,163 @@ License: MIT
69
68
 
70
69
  ## Type
71
70
 
72
- [Documentation](https://sinclairzx81.github.io/typebox/#/docs/type/overview)
71
+ [Documentation](https://sinclairzx81.github.io/typebox/#/docs/type/overview) | [Example](https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAFQJ5gKZwGZQiOByGFVAIwgA88AoSgehrgFonmXW32POvueHb7kafo16ix4ic2oBjCADsAzvACqC1FDgBeREQB0AeWIArVNJgAKAN5wbtu-Yc26cWYpVqN2y5RvAAJgBcOmi6AMowUMByAObmAJQANI7JKfbONoRoQXgQxqYweAk+cHIAhiCoQYKoYRFRsYmpTQ7pcGDYaLDAqApB3jaoIKXAADZVeuGRMVaY0EMw2YPDI3hwAL5xya2+gXDWmZX4SlPRq2tFG81X11v0dmUVfXAH2cf1Z0U3X99w23BLoyexR+INSfwyRFedRihTgwNBCLSd3sGDmpQW+ABKzhiNxdj+a3heIRrUJxLxrSgqAAjgBXYBU3YAbSJ5J+fzw-lhrLZXw5D1Q3N5JORNjwWKowtBrQAujypc1nIThJJVWr1XxnOF0cBpCqNQbDZxqAc4Kp1FpgjVtTBdQAeA4QDBmjwAPmuzlN5s8e3lCqarX8QTeMU+-u+rQFweh0TD4ZurSx0ZOfvjjiVQA)
73
72
 
74
- TypeBox provides many functions to create JSON Schema types. Each function returns a small JSON Schema fragment that can be composed into more complex types. TypeBox includes a set of functions that are used to construct JSON Schema compliant schematics as well as a set of extended functions that return schematics for constructs native to JavaScript.
73
+ TypeBox types are JSON Schema fragments that can compose into more complex types. The library offers a set of types used to construct JSON Schema compliant schematics as well as a set of extended types used to model constructs native to the JavaScript language. The schematics produced by TypeBox can be passed directly to any JSON Schema compliant validator.
75
74
 
76
75
  ## Example
77
76
 
78
- The following creates a JSON Schema type and infers with Static.
77
+ The following creates a User type and infers with Static.
79
78
 
80
79
  ```typescript
81
80
  import Type from 'typebox'
82
81
 
83
- const T = Type.Object({ // const T = {
84
- x: Type.Number(), // type: 'object',
85
- y: Type.Number(), // required: ['x', 'y', 'z'],
86
- z: Type.Number() // properties: {
87
- }) // x: { type: 'number' },
88
- // y: { type: 'number' },
89
- // z: { type: 'number' }
90
- // }
91
- // }
92
-
93
- type T = Type.Static<typeof T> // type T = {
94
- // x: number,
95
- // y: number,
96
- // z: number
97
- // }
82
+ // -------------------------------------------------------------------------------
83
+ // Type
84
+ // -------------------------------------------------------------------------------
85
+
86
+ const User = Type.Object({ // const User = {
87
+ id: Type.String(), // type: 'object',
88
+ name: Type.String(), // properties: {
89
+ email: Type.String({ format: 'email' }) // id: { type: 'string' },
90
+ }) // name: { type: 'string' },
91
+ // email: {
92
+ // type: 'string',
93
+ // format: 'email'
94
+ // }
95
+ // }
96
+ // required: [
97
+ // 'id',
98
+ // 'name',
99
+ // 'email'
100
+ // ]
101
+ // }
102
+
103
+ // -------------------------------------------------------------------------------
104
+ // Static
105
+ // -------------------------------------------------------------------------------
106
+
107
+ type User = Type.Static<typeof User> // type User = {
108
+ // id: string,
109
+ // name: string,
110
+ // email: string
111
+ // }
98
112
  ```
99
113
 
100
- Schema options can be passed on the last argument of any given type.
101
-
102
- ```typescript
103
- const T = Type.String({ // const T = {
104
- format: 'email' // type: 'string',
105
- }) // format: 'email'
106
- // }
107
-
108
- const S = Type.Number({ // const S = {
109
- minimum: 0, // type: 'number',
110
- maximum: 100 // minimum: 0,
111
- }) // maximum: 100
112
- // }
113
- ```
114
+ ## Script
114
115
 
115
- <a name="Value"></a>
116
+ [Documentation](https://sinclairzx81.github.io/typebox/#/docs/script/overview) | [Example 1](https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAFQJ5gKZwGZQiOByGFVAIwgA88AoSgehrgFonmXW32POvueHb6AygGMowMDH6Ne0mbLnNqQiADsAzvADecAKqrUUADQ69UbWAAmAQxjoAvnAC8iIgDpho8QAoABtTjBlGygMSyF0AFFA4EI4DUo4f3MALjh1UWUAc3jbPwCgkLDjfThUMhtlc1U4SJhopFi4eITlSxBUFLSAjKMmkpBLYAAbDph0jMa4HPjCNCLTC2t0J3CAN0tBgFdFgB5egAVgIQBrbd19IyPUJAgMaqjCAD44ADIJhL3LWGB17YB5EGipxMFyuNzutUeD3iUO8AEpqHQpPJkSiUZIAEqoDCDVBCCSI1GEom8RQqVQQHEuQYQDKeM5QWEJJnMlmstksxFxdncnm83mIhIzdr4CDEABWuJgeAMvT5cvlbIFcDA2DQX1QqhSXIVOt1SoSwGSDSFKTwnUyeEmMt1Nvl+rgLTaWrgJvw5oylts1ttPu59tQ-SGztdZtGXU9st9UYSSq9kejvqVUFQAEcNsBk0aANrxhO2+14Q3St55qMFx2oYu50s6gsBgaDKg1sv0BIAXWrzbliKmSjUFNQVJpdJMZisNkZec5na7-NbLqIptFErx0pns7985VEDVtQ1WvXG8V84NRq0Ifdnu9R4V9orwcXbrDFqth5vzP9geGxsfobGEffW95zjQC7XnZM0wzVBs0Lcw8A7UDu3oKYCWJND0IUREBBgaxDkkDCCOJaghTmRxnDQNwcNqIRtiFMF6SeJCF1mekyO1RC5yZQ0RjGa8OM3Jl71SZ9ujfRClXrINhLGMTQJ7YiiDmMdFjI5AKOw3CaLo256WUmxGMREjdIWGw2NkwClW46Suj4-jj0E1pUAAfh4mzzPfCSvxc6zMncm95KAA) | [Example 2](https://www.typescriptlang.org/play/#code/JYWwDg9gTgLgBAFQJ5gKZwGZQiOByGFVAIwgA88AoSgehrgFonmXW32POvnb7k1ejbsJGj21AMYQAdgGd4AUWkxghOAF5ERAHQB5YgCtUEmAAoA3pThxgAEwBcWtNoDKMKMGkBzUwEpKAL7+lFJy8ACqsqhQGk6o2gCSytEYAIYSqKYA2koqhAC6ADRwltbSqSCojvzxbh7efoVWcKggqcAANtU6dZ4+-kGSMvJwkdHhYLapMOiaNdoKAG6pHQCu05nzSTNQUSbZzfMACsASANamY1DF8wDSqEi6GKa5qki+vk3Wx6mwwCumea6ECqS5Ra5xbT3R7PV6ED7+fIfah0IRidEYzHcQQAJVQGA6xhggixpLJWKGcgghO0HQgPiuvmszJZrLZ7NZqNKHJ5vL5vNR1kIaEceAghiJeC+-Jlsp5grgYGwaD+qFkjm5cq1WoV1jsGrgwqq+Hk9S8eDgAWl2pt-N1cHKlQNRtFpr6FqtzVt3o59ta7S6JUNRFd7ndlq9PqjzIVnuj8esCqgqAAjqtgMmHHAspGE977Xg7FK4Lm8zaC47UMXS2WdfQWXh-Z0qLWfQr8jXWzLUQFKbJqfE6QzwRMpjMmQmuZ2u3yFS78OKjCYpdOZ-L64rldEVGqNau1+z7fqg-O8G7vB7rQfuxuyhVjeZgyKTWGL5ar9fZ7eWm1Os6Qy+Zoevun4xhucagXaG7JmmGaoFmWSFrYeAdpBUERiS5JYdhnCCG40ynJhOHEcR1BGqM4KxPM+EqBIAA8RoQBgFHRAAfLKqLkVcsSamh67Mse55eB+fFsgqlaOEJImiSyCpNoGQkgWhPZkUQLFQKOGxUT0MAEfRjHMVcmkzOxcCcWpRmTFpmi8TJnIboJr7CUpkHifeAD8klOdJdlmRu8meXAim+Ye9ABEAA)
116
117
 
117
- ## Value
118
+ TypeBox can transform TypeScript definitions into JSON Schema. The Script function provides an optional programmatic syntax to rapidly convert type definitions into JSON Schema, or serve more generally as an alternative to Type.* builders. The Script function is designed to handle a wide array of complex TypeScript type-level expressions.
118
119
 
119
- [Documentation](https://sinclairzx81.github.io/typebox/#/docs/value/overview)
120
+ ### Example
120
121
 
121
- The Value submodule provides functions for validation and other typed operations on JavaScript values. It includes functions such as Check, Parse, Clone, Encode, and Decode, as well as advanced functions for performing structural Diff and Patch operations on dynamic JavaScript values.
122
+ The following uses the Script to parse interfaces into JSON Schema.
122
123
 
123
124
  ```typescript
124
- import Value from 'typebox/value'
125
- ```
126
-
127
- ### Example
125
+ import Type from 'typebox'
128
126
 
129
- The following uses the Value module to Parse a value.
127
+ // -------------------------------------------------------------------------------
128
+ // Script
129
+ // -------------------------------------------------------------------------------
130
130
 
131
- ```typescript
132
- const T = Type.Object({
133
- x: Type.Number(),
134
- y: Type.Number(),
135
- z: Type.Number()
136
- })
137
-
138
- const A = Value.Parse(T, { // const A: {
139
- x: 1, // x: number,
140
- y: 0, // y: number,
141
- z: 0 // z: number
142
- }) // } = ...
143
- ```
131
+ const { User, UserUpdate } = Type.Script(`
144
132
 
145
- ## Script
133
+ interface Entity {
134
+ id: string
135
+ }
146
136
 
147
- [Documentation](https://sinclairzx81.github.io/typebox/#/docs/script/overview)
137
+ interface User extends Entity {
138
+ name: string,
139
+ email: string
140
+ }
148
141
 
149
- TypeBox includes a runtime TypeScript DSL engine that can transform TypeScript syntax into JSON Schema. The engine is implemented at runtime and within the TypeScript type system.
142
+ type UserUpdate = Evaluate<
143
+ Pick<User, keyof Entity> &
144
+ Partial<Omit<User, keyof Entity>>
145
+ >
146
+ `)
150
147
 
151
- ```typescript
152
- // ----------------------------------------------------------
153
- // Script
154
- // ----------------------------------------------------------
155
- const T = Type.Script(`{
156
- x: number,
157
- y: string,
158
- z: boolean
159
- }`)
160
-
161
- // ----------------------------------------------------------
148
+ // -------------------------------------------------------------------------------
162
149
  // Reflect
163
- // ----------------------------------------------------------
164
- T.type // 'object'
165
- T.required // ['x', 'y', 'z']
166
- T.properties // { x: ..., y: ..., z: ... }
167
-
168
- // ----------------------------------------------------------
169
- // Computed
170
- // ----------------------------------------------------------
171
- const S = Type.Script({ T }, `{
172
- [K in keyof T]: T[K] | null
173
- }`)
174
-
175
- // ----------------------------------------------------------
176
- // Inference
177
- // ----------------------------------------------------------
178
- type S = Type.Static<typeof S> // type S = {
179
- // x: number | null,
180
- // y: string | null,
181
- // z: boolean | null
182
- // }
150
+ // -------------------------------------------------------------------------------
151
+
152
+ console.log(User) // {
153
+ // type: 'object',
154
+ // properties: {
155
+ // id: { type: 'string' },
156
+ // name: { type: 'string' },
157
+ // email: { type: 'string' }
158
+ // },
159
+ // required: [
160
+ // 'id',
161
+ // 'name',
162
+ // 'email'
163
+ // ]
164
+ // }
165
+
166
+ console.log(UserUpdate) // {
167
+ // type: 'object',
168
+ // properties: {
169
+ // id: { type: 'string' },
170
+ // name: { type: 'string' },
171
+ // email: { type: 'string' }
172
+ // },
173
+ // required: ['id']
174
+ // }
175
+
176
+ // -------------------------------------------------------------------------------
177
+ // Static
178
+ // -------------------------------------------------------------------------------
179
+
180
+ type User = Type.Static<typeof User> // type User = {
181
+ // id: string,
182
+ // name: string,
183
+ // email: string
184
+ // }
185
+
186
+ type UserUpdate = Type.Static<typeof UserUpdate> // type UserUpdate = {
187
+ // id: string,
188
+ // name?: string,
189
+ // email?: string
190
+ // }
191
+
183
192
  ```
184
193
 
185
194
  <a name="Schema"></a>
186
195
 
187
196
  ## Schema
188
197
 
189
- [Documentation](https://sinclairzx81.github.io/typebox/#/docs/schema/overview)
198
+ [Documentation](https://sinclairzx81.github.io/typebox/#/docs/schema/overview) | [Example 1](https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAZQMYAsCmICGcBmUIhwDkMAnmGgEYQAeA9AM6oaZEBQokscAKuWrnyES-ajXZs6dOAFo58hYqXKVqteo0zJ0gMIEwwADZptszeYuWr8tmyQQAdg3gBVBmihwAvImZYAdHrgRmgAFHwU-gDylABWaEgwoQDebHBwwAAmAFy8-P4IMFDADgDmoQCUADRpcA6YIGi5EWgFRSXl1bUsRs35hcVlKbjQWDC5RD2GRHAAvhVs8wum1qtr61pScAAKmFDuKxtHx6q29k7wAK7unj5uHv67+2HJ6W-vH5-vW+fOcNceXKpdJZCYANgArDgAIyYABMlAAzEgACyZCFoME4ADsmAAHJQAJxIAAMmWhRCqX2pcC2IJycGcg1KNXS9UaEwBUEpNN5fO+0jZDSajPaZVZcCmnJuAAFMgRMCV-PYQDN+by6ZKsL1RczFhV1YajR8trNvHB-JagA) | [Example 2](https://www.typescriptlang.org/play/?#code/JYWwDg9gTgLgBAZQMYAsCmICGcBmUIhwDkMAnmGgEYQAeA9AM6oaZEBQbddcAtH-wMFDhI0WPESenbgGECYYABs003pPUbNW-hyQQAdg3gBVBmihwAvImZYAdHPBK0ACgDebOHDIUAXMQhKACs0JBgiABpPODB8ClhgNAZ-Dy8vYAATFO9yNH8iIyhgfQBzIjgAXyi0uH1MEDy4Nxy-YkLissrqtJYlbJ9Ggpgi0vKK6KroqDQARwBXYGmsuABtaK8iTMi4deI6hu3dol7Fdi8AXTYKgEoOLjVtR6en1QAFTCgzVWef38ldAxGOBzMwWaymcx2d6fVzNGrwhGIuD3PSGeAg8wpaKZfIANgArDgAIyYABMlAAzEgACwZfFoXE4ADsmAAHJQAJxIAAMGSJ2yRiPu6WW7VK3X2gwxUAFgrl8q8wtq9UaYpK3RO+WlAAEMgRMMU7HoQOUFXKlZq4GqrtczXb7fD7hUrHA7G6gA)
190
199
 
191
- The Schema submodule is a low level JSON Schema spec compliant validation system that supports Drafts 3 through to 2020-12. This validation system is decoupled from both Type.* and Value.* submodules and is designed to be an ultra lightweight, high performance alternative to Ajv for compiling and validating with native JSON Schema.
192
-
193
- ```typescript
194
- import Schema from 'typebox/schema'
195
- ```
200
+ TypeBox includes high performance validation compiler for JSON Schema Drafts 3 through to 2020-12. The compiler supports both TypeBox and JSON Schema, and will convert schematics into high performance validation routines. The compiler is designed to be a lightweight spec compliant alternative to Ajv for high-throughput applications.
196
201
 
197
202
  ### Example
198
203
 
199
- The following uses the Schema submodule to compile and parse from JSON Schema.
204
+ The following uses the Schema submodule to compile a TypeBox type.
200
205
 
201
206
  ```typescript
202
- // ----------------------------------------------------------
207
+ import Schema from 'typebox/schema'
208
+
209
+ // -------------------------------------------------------------------------------
203
210
  // Compile
204
- // ----------------------------------------------------------
205
- const C = Schema.Compile({
206
- type: 'object',
207
- required: ['x', 'y', 'z'],
208
- properties: {
209
- x: { type: 'number' },
210
- y: { type: 'number' },
211
- z: { type: 'number' }
212
- }
213
- })
214
-
215
- // ----------------------------------------------------------
211
+ // -------------------------------------------------------------------------------
212
+
213
+ const User = Schema.Compile(Type.Object({
214
+ id: Type.String(),
215
+ name: Type.String(),
216
+ email: Type.String({ format: 'email' })
217
+ }))
218
+
219
+ // -------------------------------------------------------------------------------
216
220
  // Parse
217
- // ----------------------------------------------------------
218
- const R = C.Parse({ x: 0, y: 0, z: 0 }) // const R: {
219
- // x: number,
220
- // y: number,
221
- // z: number
222
- // } = ...
221
+ // -------------------------------------------------------------------------------
222
+
223
+ const user = User.Parse({ // const user: {
224
+ id: '65f1a2b3c4d5e6f7a8b9c0d1', // id: string,
225
+ name: 'user', // name: string,
226
+ email: 'user@domain.com' // email: string
227
+ }) // } = ...
223
228
  ```
224
229
 
225
230
  <a name="Versions"></a>
@@ -228,25 +233,10 @@ const R = C.Parse({ x: 0, y: 0, z: 0 }) // const R: {
228
233
 
229
234
  TypeBox provides two distinct versions that span two generations of the TypeScript compiler.
230
235
 
231
- ### Version 0.x
232
-
233
- ```bash
234
- $ npm install @sinclair/typebox # 0.x - LTS | TS 4-6
235
- ```
236
-
237
- Developed against TypeScript 4-6 and maintained under Long Term Support (LTS) for existing infrastructure on the 0.x revision line. ESM and CJS compatible.
238
-
239
- ### Version 1.x
240
-
241
- ```bash
242
- $ npm install typebox # 1.x - Latest | TS 7 Native
243
- ```
244
-
245
- Developed against the TypeScript 7 native compiler with advanced type inference and JSON Schema 2020-12 compliant validation, with backwards compatibility for `0.x` types. ESM only.
246
-
247
- ### Additional
248
-
249
- The `1.x` version is recommended for most new projects and is the active development line that targets optimizations enabled by the TypeScript 7 native compiler. The `0.x` version is maintained under LTS for environments requiring CJS and ESM compatibility as well as support for older TypeScript compiler versions. For issues relating to `0.x` please submit them to the [TypeBox 0.x](https://github.com/sinclairzx81/sinclair-typebox) repository.
236
+ | Version | TypeScript | Description |
237
+ | :--- | :--- | :--- |
238
+ | **1.x** | **6.0 - 7.0+** | **Latest.** Developed against the TypeScript 7 native compiler. Provides advanced type inference and native JSON Schema 2020-12 support. Includes backwards compatibility with `0.x` types. **ESM only.** |
239
+ | **0.x** | **5.0 - 6.0** | **LTS.** Developed against older TypeScript versions and actively maintained under Long Term Support. Compatible with both **ESM and CJS**. Issues should be submitted to the [Sinclair TypeBox](https://github.com/sinclairzx81/sinclair-typebox) repository. |
250
240
 
251
241
  ## Contribute
252
242