typebox 1.2.10 → 1.2.12
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.
- package/build/guard/guard.d.mts +2 -2
- package/build/guard/guard.mjs +2 -2
- package/build/type/engine/call/distribute_arguments.mjs +1 -1
- package/build/type/engine/call/resolve_arguments.mjs +2 -2
- package/build/type/engine/cyclic/check.mjs +1 -1
- package/build/type/engine/evaluate/distribute.mjs +3 -3
- package/build/type/engine/instantiate.mjs +1 -1
- package/build/type/engine/object/from_union.mjs +2 -2
- package/build/type/engine/template_literal/decode.mjs +3 -3
- package/build/type/engine/template_literal/encode.mjs +2 -2
- package/build/type/engine/template_literal/is_finite.mjs +1 -1
- package/build/type/extends/extends_left.d.mts +3 -1
- package/build/type/extends/extends_left.mjs +12 -9
- package/build/type/extends/extends_right.mjs +2 -2
- package/build/type/extends/inference.mjs +1 -1
- package/build/type/extends/object.d.mts +8 -1
- package/build/type/extends/object.mjs +25 -3
- package/build/type/extends/parameters.mjs +2 -2
- package/build/type/extends/record.d.mts +13 -0
- package/build/type/extends/record.mjs +23 -0
- package/build/type/extends/tuple.mjs +3 -3
- package/build/type/extends/union.mjs +2 -2
- package/build/type/script/token/internal/guard.d.mts +1 -1
- package/build/type/script/token/internal/guard.mjs +1 -1
- package/build/type/script/token/internal/take.mjs +1 -1
- package/build/type/script/token/until.mjs +2 -2
- package/build/type/types/record.d.mts +11 -5
- package/build/type/types/record.mjs +12 -6
- package/build/value/shared/union_priority_sort.mjs +1 -1
- package/package.json +1 -1
package/build/guard/guard.d.mts
CHANGED
|
@@ -47,8 +47,8 @@ export declare function IsMinLength(value: string, length: number): boolean;
|
|
|
47
47
|
export declare function Every<T>(value: T[], offset: number, callback: (value: T, index: number) => boolean): boolean;
|
|
48
48
|
/** Returns true if all elements from offset satisfy the callback, visiting every element regardless of failure */
|
|
49
49
|
export declare function EveryAll<T>(value: T[], offset: number, callback: (value: T, index: number) => boolean): boolean;
|
|
50
|
-
/**
|
|
51
|
-
export declare function
|
|
50
|
+
/** Shifts the left-most element from an array and dispatches to the true arm, or the false arm if empty */
|
|
51
|
+
export declare function ShiftLeft<T, True extends (left: T, right: T[]) => unknown, False extends () => unknown>(array: T[], true_: True, false_: False): ReturnType<True> | ReturnType<False>;
|
|
52
52
|
/** Returns true if the PropertyKey is Unsafe (ref: prototype-pollution). */
|
|
53
53
|
export declare function IsUnsafePropertyKey(key: PropertyKey): boolean;
|
|
54
54
|
/** Returns true if this value has this property key */
|
package/build/guard/guard.mjs
CHANGED
|
@@ -162,8 +162,8 @@ export function EveryAll(value, offset, callback) {
|
|
|
162
162
|
}
|
|
163
163
|
return result;
|
|
164
164
|
}
|
|
165
|
-
/**
|
|
166
|
-
export function
|
|
165
|
+
/** Shifts the left-most element from an array and dispatches to the true arm, or the false arm if empty */
|
|
166
|
+
export function ShiftLeft(array, true_, false_) {
|
|
167
167
|
return (IsEqual(array.length, 0) ? false_() : true_(array[0], array.slice(1)));
|
|
168
168
|
}
|
|
169
169
|
// --------------------------------------------------------------------------
|
|
@@ -19,7 +19,7 @@ function BuildDistributionArray(parameters, names) {
|
|
|
19
19
|
return parameters.reduce((result, left) => [...result, names.includes(left.name)], []);
|
|
20
20
|
}
|
|
21
21
|
function ZipDistributionArray(arguments_, distributionArray, result = []) {
|
|
22
|
-
return Guard.
|
|
22
|
+
return Guard.ShiftLeft(arguments_, (argumentLeft, argumentRight) => Guard.ShiftLeft(distributionArray, (booleanLeft, booleanRight) => ZipDistributionArray(argumentRight, booleanRight, [...result, [booleanLeft, argumentLeft]]), () => result), () => result);
|
|
23
23
|
}
|
|
24
24
|
function Expand(type) {
|
|
25
25
|
return (IsUnion(type)
|
|
@@ -23,10 +23,10 @@ function BindArgument(context, state, name, extends_, type) {
|
|
|
23
23
|
function BindArguments(context, state, parameterLeft, parameterRight, arguments_) {
|
|
24
24
|
const instantiatedExtends = InstantiateType(context, state, parameterLeft.extends);
|
|
25
25
|
const instantiatedEquals = InstantiateType(context, state, parameterLeft.equals);
|
|
26
|
-
return Guard.
|
|
26
|
+
return Guard.ShiftLeft(arguments_, (left, right) => BindParameters(BindArgument(context, state, parameterLeft['name'], instantiatedExtends, left), state, parameterRight, right), () => BindParameters(BindArgument(context, state, parameterLeft['name'], instantiatedExtends, instantiatedEquals), state, parameterRight, []));
|
|
27
27
|
}
|
|
28
28
|
function BindParameters(context, state, parameters, arguments_) {
|
|
29
|
-
return Guard.
|
|
29
|
+
return Guard.ShiftLeft(parameters, (left, right) => BindArguments(context, state, left, right, arguments_), () => context);
|
|
30
30
|
}
|
|
31
31
|
export function ResolveArgumentsContext(context, state, parameters, arguments_) {
|
|
32
32
|
return BindParameters(context, state, parameters, arguments_);
|
|
@@ -24,7 +24,7 @@ function FromProperties(stack, context, properties) {
|
|
|
24
24
|
return FromTypes(stack, context, types);
|
|
25
25
|
}
|
|
26
26
|
function FromTypes(stack, context, types) {
|
|
27
|
-
return Guard.
|
|
27
|
+
return Guard.ShiftLeft(types, (left, right) => FromType(stack, context, left)
|
|
28
28
|
? true
|
|
29
29
|
: FromTypes(stack, context, right), () => false);
|
|
30
30
|
}
|
|
@@ -31,15 +31,15 @@ function DistributeOperation(left, right) {
|
|
|
31
31
|
return result;
|
|
32
32
|
}
|
|
33
33
|
function DistributeType(type, types, result = []) {
|
|
34
|
-
return Guard.
|
|
34
|
+
return Guard.ShiftLeft(types, (left, right) => DistributeType(type, right, [...result, DistributeOperation(type, left)]), () => Guard.IsEqual(result.length, 0)
|
|
35
35
|
? [type]
|
|
36
36
|
: result);
|
|
37
37
|
}
|
|
38
38
|
function DistributeUnion(types, distribution, result = []) {
|
|
39
|
-
return Guard.
|
|
39
|
+
return Guard.ShiftLeft(types, (left, right) => DistributeUnion(right, distribution, [...result, ...Distribute([left], distribution)]), () => result);
|
|
40
40
|
}
|
|
41
41
|
export function Distribute(types, result = []) {
|
|
42
|
-
return Guard.
|
|
42
|
+
return Guard.ShiftLeft(types, (left, right) => IsUnion(left)
|
|
43
43
|
? Distribute(right, DistributeUnion(left.anyOf, result))
|
|
44
44
|
: Distribute(right, DistributeType(left, result)), () => result);
|
|
45
45
|
}
|
|
@@ -70,7 +70,7 @@ export function State(callstack, visited) {
|
|
|
70
70
|
return { callstack, visited };
|
|
71
71
|
}
|
|
72
72
|
export function CanInstantiate(types) {
|
|
73
|
-
return Guard.
|
|
73
|
+
return Guard.ShiftLeft(types, (left, right) => IsRef(left)
|
|
74
74
|
? false
|
|
75
75
|
: CanInstantiate(right), () => true);
|
|
76
76
|
}
|
|
@@ -11,9 +11,9 @@ function CollapseUnionProperties(left, right) {
|
|
|
11
11
|
return result;
|
|
12
12
|
}
|
|
13
13
|
function ReduceVariants(types, result) {
|
|
14
|
-
return Guard.
|
|
14
|
+
return Guard.ShiftLeft(types, (left, right) => ReduceVariants(right, CollapseUnionProperties(result, FromType(left))), () => result);
|
|
15
15
|
}
|
|
16
16
|
export function FromUnion(types) {
|
|
17
|
-
return Guard.
|
|
17
|
+
return Guard.ShiftLeft(types, (left, right) => ReduceVariants(right, FromType(left)), () => Unreachable());
|
|
18
18
|
}
|
|
19
19
|
// deno-coverage-ignore-stop
|
|
@@ -9,13 +9,13 @@ import { ParsePatternIntoTypes } from '../patterns/pattern.mjs';
|
|
|
9
9
|
import { IsTemplateLiteralFinite } from './is_finite.mjs';
|
|
10
10
|
import { TemplateLiteralCreate } from './create.mjs';
|
|
11
11
|
function FromLiteralPush(variants, value, result = []) {
|
|
12
|
-
return Guard.
|
|
12
|
+
return Guard.ShiftLeft(variants, (left, right) => FromLiteralPush(right, value, [...result, `${left}${value}`]), () => result);
|
|
13
13
|
}
|
|
14
14
|
function FromLiteral(variants, value) {
|
|
15
15
|
return (Guard.IsEqual(variants.length, 0) ? [`${value}`] : FromLiteralPush(variants, value));
|
|
16
16
|
}
|
|
17
17
|
function FromUnion(variants, types, result = []) {
|
|
18
|
-
return Guard.
|
|
18
|
+
return Guard.ShiftLeft(types, (left, right) => FromUnion(variants, right, [...result, ...FromType(variants, left)]), () => result);
|
|
19
19
|
}
|
|
20
20
|
// ------------------------------------------------------------------
|
|
21
21
|
// deno-coverage-ignore-start - symmetric unreachable | internal
|
|
@@ -33,7 +33,7 @@ function FromType(variants, type) {
|
|
|
33
33
|
return result;
|
|
34
34
|
}
|
|
35
35
|
function DecodeFromSpan(variants, types) {
|
|
36
|
-
return Guard.
|
|
36
|
+
return Guard.ShiftLeft(types, (left, right) => DecodeFromSpan(FromType(variants, left), right), () => variants);
|
|
37
37
|
}
|
|
38
38
|
function VariantsToLiterals(variants) {
|
|
39
39
|
return variants.map(variant => Literal(variant));
|
|
@@ -50,7 +50,7 @@ function EncodeEnum(values, right, pattern) {
|
|
|
50
50
|
return EncodeType(evaluated, right, pattern);
|
|
51
51
|
}
|
|
52
52
|
function EncodeUnion(types, right, pattern, result = []) {
|
|
53
|
-
return Guard.
|
|
53
|
+
return Guard.ShiftLeft(types, (head, tail) => EncodeUnion(tail, right, pattern, [...result, EncodeType(head, [], '')]), () => EncodeTypes(right, `${pattern}(${JoinString(result)})`));
|
|
54
54
|
}
|
|
55
55
|
function EncodeType(type, right, pattern) {
|
|
56
56
|
return (IsEnum(type) ? EncodeEnum(type.enum, right, pattern) :
|
|
@@ -66,7 +66,7 @@ function EncodeType(type, right, pattern) {
|
|
|
66
66
|
NeverPattern);
|
|
67
67
|
}
|
|
68
68
|
function EncodeTypes(types, pattern) {
|
|
69
|
-
return Guard.
|
|
69
|
+
return Guard.ShiftLeft(types, (left, right) => EncodeType(left, right, pattern), () => pattern);
|
|
70
70
|
}
|
|
71
71
|
function EncodePattern(types) {
|
|
72
72
|
const encoded = EncodeTypes(types, '');
|
|
@@ -6,7 +6,7 @@ function FromLiteral(_value) {
|
|
|
6
6
|
return true;
|
|
7
7
|
}
|
|
8
8
|
function FromTypesReduce(types) {
|
|
9
|
-
return Guard.
|
|
9
|
+
return Guard.ShiftLeft(types, (left, right) => FromType(left)
|
|
10
10
|
? FromTypesReduce(right)
|
|
11
11
|
: false, () => true);
|
|
12
12
|
}
|
|
@@ -16,6 +16,7 @@ import { type TExtendsNull } from './null.mjs';
|
|
|
16
16
|
import { type TExtendsNumber } from './number.mjs';
|
|
17
17
|
import { type TExtendsObject } from './object.mjs';
|
|
18
18
|
import { type TExtendsPromise } from './promise.mjs';
|
|
19
|
+
import { type TExtendsRecord } from './record.mjs';
|
|
19
20
|
import { type TExtendsString } from './string.mjs';
|
|
20
21
|
import { type TExtendsSymbol } from './symbol.mjs';
|
|
21
22
|
import { type TExtendsTemplateLiteral } from './template_literal.mjs';
|
|
@@ -42,6 +43,7 @@ import { type TNull } from '../types/null.mjs';
|
|
|
42
43
|
import { type TNumber } from '../types/number.mjs';
|
|
43
44
|
import { type TObject } from '../types/object.mjs';
|
|
44
45
|
import { type TPromise } from '../types/promise.mjs';
|
|
46
|
+
import { type TRecord } from '../types/record.mjs';
|
|
45
47
|
import { type TSchema } from '../types/schema.mjs';
|
|
46
48
|
import { type TString } from '../types/string.mjs';
|
|
47
49
|
import { type TSymbol } from '../types/symbol.mjs';
|
|
@@ -53,5 +55,5 @@ import { type TProperties } from '../types/properties.mjs';
|
|
|
53
55
|
import { type TUnion } from '../types/union.mjs';
|
|
54
56
|
import { type TVoid } from '../types/void.mjs';
|
|
55
57
|
import * as Result from './result.mjs';
|
|
56
|
-
export type TExtendsLeft<Inferred extends TProperties, Left extends TSchema, Right extends TSchema> = (Left extends TAny ? TExtendsAny<Inferred, Left, Right> : Left extends TArray<infer Items extends TSchema> ? TExtendsArray<Inferred, Left, Items, Right> : Left extends TAsyncIterator<infer Type extends TSchema> ? TExtendsAsyncIterator<Inferred, Type, Right> : Left extends TBigInt ? TExtendsBigInt<Inferred, Left, Right> : Left extends TBoolean ? TExtendsBoolean<Inferred, Left, Right> : Left extends TConstructor<infer Parameters extends TSchema[], infer InstanceType extends TSchema> ? TExtendsConstructor<Inferred, Parameters, InstanceType, Right> : Left extends TDependent<infer If extends TSchema, infer Then extends TSchema, infer Else extends TSchema> ? TExtendsDependent<Inferred, If, Then, Else, Right> : Left extends TEnum<infer Values extends TEnumValue[]> ? TExtendsEnum<Inferred, Values, Right> : Left extends TFunction<infer Parameters extends TSchema[], infer ReturnType extends TSchema> ? TExtendsFunction<Inferred, Parameters, ReturnType, Right> : Left extends TInteger ? TExtendsInteger<Inferred, Left, Right> : Left extends TIntersect<infer Types extends TSchema[]> ? TExtendsIntersect<Inferred, Types, Right> : Left extends TIterator<infer Type extends TSchema> ? TExtendsIterator<Inferred, Type, Right> : Left extends TLiteral ? TExtendsLiteral<Inferred, Left, Right> : Left extends TNever ? TExtendsNever<Inferred, Left, Right> : Left extends TNull ? TExtendsNull<Inferred, Left, Right> : Left extends TNumber ? TExtendsNumber<Inferred, Left, Right> : Left extends TObject<infer Properties extends TProperties> ? TExtendsObject<Inferred, Properties, Right> : Left extends TPromise<infer Type extends TSchema> ? TExtendsPromise<Inferred, Type, Right> : Left extends TString ? TExtendsString<Inferred, Left, Right> : Left extends TSymbol ? TExtendsSymbol<Inferred, Left, Right> : Left extends TTemplateLiteral<infer Pattern extends string> ? TExtendsTemplateLiteral<Inferred, Pattern, Right> : Left extends TTuple<infer Types extends TSchema[]> ? TExtendsTuple<Inferred, Types, Right> : Left extends TUndefined ? TExtendsUndefined<Inferred, Left, Right> : Left extends TUnion<infer Types extends TSchema[]> ? TExtendsUnion<Inferred, Types, Right> : Left extends TUnknown ? TExtendsUnknown<Inferred, Left, Right> : Left extends TVoid ? TExtendsVoid<Inferred, Left, Right> : Result.TExtendsFalse);
|
|
58
|
+
export type TExtendsLeft<Inferred extends TProperties, Left extends TSchema, Right extends TSchema> = (Left extends TAny ? TExtendsAny<Inferred, Left, Right> : Left extends TArray<infer Items extends TSchema> ? TExtendsArray<Inferred, Left, Items, Right> : Left extends TAsyncIterator<infer Type extends TSchema> ? TExtendsAsyncIterator<Inferred, Type, Right> : Left extends TBigInt ? TExtendsBigInt<Inferred, Left, Right> : Left extends TBoolean ? TExtendsBoolean<Inferred, Left, Right> : Left extends TConstructor<infer Parameters extends TSchema[], infer InstanceType extends TSchema> ? TExtendsConstructor<Inferred, Parameters, InstanceType, Right> : Left extends TDependent<infer If extends TSchema, infer Then extends TSchema, infer Else extends TSchema> ? TExtendsDependent<Inferred, If, Then, Else, Right> : Left extends TEnum<infer Values extends TEnumValue[]> ? TExtendsEnum<Inferred, Values, Right> : Left extends TFunction<infer Parameters extends TSchema[], infer ReturnType extends TSchema> ? TExtendsFunction<Inferred, Parameters, ReturnType, Right> : Left extends TInteger ? TExtendsInteger<Inferred, Left, Right> : Left extends TIntersect<infer Types extends TSchema[]> ? TExtendsIntersect<Inferred, Types, Right> : Left extends TIterator<infer Type extends TSchema> ? TExtendsIterator<Inferred, Type, Right> : Left extends TLiteral ? TExtendsLiteral<Inferred, Left, Right> : Left extends TNever ? TExtendsNever<Inferred, Left, Right> : Left extends TNull ? TExtendsNull<Inferred, Left, Right> : Left extends TNumber ? TExtendsNumber<Inferred, Left, Right> : Left extends TObject<infer Properties extends TProperties> ? TExtendsObject<Inferred, Properties, Right> : Left extends TPromise<infer Type extends TSchema> ? TExtendsPromise<Inferred, Type, Right> : Left extends TRecord<infer Pattern extends string, infer Value extends TSchema> ? TExtendsRecord<Inferred, Pattern, Value, Right> : Left extends TString ? TExtendsString<Inferred, Left, Right> : Left extends TSymbol ? TExtendsSymbol<Inferred, Left, Right> : Left extends TTemplateLiteral<infer Pattern extends string> ? TExtendsTemplateLiteral<Inferred, Pattern, Right> : Left extends TTuple<infer Types extends TSchema[]> ? TExtendsTuple<Inferred, Types, Right> : Left extends TUndefined ? TExtendsUndefined<Inferred, Left, Right> : Left extends TUnion<infer Types extends TSchema[]> ? TExtendsUnion<Inferred, Types, Right> : Left extends TUnknown ? TExtendsUnknown<Inferred, Left, Right> : Left extends TVoid ? TExtendsVoid<Inferred, Left, Right> : Result.TExtendsFalse);
|
|
57
59
|
export declare function ExtendsLeft<Inferred extends TProperties, Left extends TSchema, Right extends TSchema>(inferred: Inferred, left: Left, right: Right): TExtendsLeft<Inferred, Left, Right>;
|
|
@@ -17,6 +17,7 @@ import { ExtendsNull } from './null.mjs';
|
|
|
17
17
|
import { ExtendsNumber } from './number.mjs';
|
|
18
18
|
import { ExtendsObject } from './object.mjs';
|
|
19
19
|
import { ExtendsPromise } from './promise.mjs';
|
|
20
|
+
import { ExtendsRecord } from './record.mjs';
|
|
20
21
|
import { ExtendsString } from './string.mjs';
|
|
21
22
|
import { ExtendsSymbol } from './symbol.mjs';
|
|
22
23
|
import { ExtendsTemplateLiteral } from './template_literal.mjs';
|
|
@@ -46,6 +47,7 @@ import { IsNull } from '../types/null.mjs';
|
|
|
46
47
|
import { IsNumber } from '../types/number.mjs';
|
|
47
48
|
import { IsObject } from '../types/object.mjs';
|
|
48
49
|
import { IsPromise } from '../types/promise.mjs';
|
|
50
|
+
import { IsRecord, RecordPattern, RecordValue } from '../types/record.mjs';
|
|
49
51
|
import { IsString } from '../types/string.mjs';
|
|
50
52
|
import { IsSymbol } from '../types/symbol.mjs';
|
|
51
53
|
import { IsTemplateLiteral } from '../types/template_literal.mjs';
|
|
@@ -74,13 +76,14 @@ export function ExtendsLeft(inferred, left, right) {
|
|
|
74
76
|
IsNumber(left) ? ExtendsNumber(inferred, left, right) :
|
|
75
77
|
IsObject(left) ? ExtendsObject(inferred, left.properties, right) :
|
|
76
78
|
IsPromise(left) ? ExtendsPromise(inferred, left.item, right) :
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
IsRecord(left) ? ExtendsRecord(inferred, RecordPattern(left), RecordValue(left), right) :
|
|
80
|
+
IsString(left) ? ExtendsString(inferred, left, right) :
|
|
81
|
+
IsSymbol(left) ? ExtendsSymbol(inferred, left, right) :
|
|
82
|
+
IsTemplateLiteral(left) ? ExtendsTemplateLiteral(inferred, left.pattern, right) :
|
|
83
|
+
IsTuple(left) ? ExtendsTuple(inferred, left.items, right) :
|
|
84
|
+
IsUndefined(left) ? ExtendsUndefined(inferred, left, right) :
|
|
85
|
+
IsUnion(left) ? ExtendsUnion(inferred, left.anyOf, right) :
|
|
86
|
+
IsUnknown(left) ? ExtendsUnknown(inferred, left, right) :
|
|
87
|
+
IsVoid(left) ? ExtendsVoid(inferred, left, right) :
|
|
88
|
+
Result.ExtendsFalse());
|
|
86
89
|
}
|
|
@@ -27,14 +27,14 @@ function ExtendsRightEnum(inferred, left, right) {
|
|
|
27
27
|
return ExtendsLeft(inferred, left, evaluated);
|
|
28
28
|
}
|
|
29
29
|
function ExtendsRightIntersect(inferred, left, right) {
|
|
30
|
-
return Guard.
|
|
30
|
+
return Guard.ShiftLeft(right, (head, tail) => Result.Match(ExtendsLeft(inferred, left, head), inferred => ExtendsRightIntersect(inferred, left, tail), () => Result.ExtendsFalse()), () => Result.ExtendsTrue(inferred));
|
|
31
31
|
}
|
|
32
32
|
function ExtendsRightTemplateLiteral(inferred, left, right) {
|
|
33
33
|
const evaluated = EvaluateTemplateLiteral(right);
|
|
34
34
|
return ExtendsLeft(inferred, left, evaluated);
|
|
35
35
|
}
|
|
36
36
|
function ExtendsRightUnion(inferred, left, right) {
|
|
37
|
-
return Guard.
|
|
37
|
+
return Guard.ShiftLeft(right, (head, tail) => Result.Match(ExtendsLeft(inferred, left, head), inferred => Result.ExtendsTrue(inferred), () => ExtendsRightUnion(inferred, left, tail)), () => Result.ExtendsFalse());
|
|
38
38
|
}
|
|
39
39
|
export function ExtendsRight(inferred, left, right) {
|
|
40
40
|
return (IsAny(right) ? ExtendsRightAny(inferred, left) :
|
|
@@ -46,7 +46,7 @@ export function TryInferable(type) {
|
|
|
46
46
|
undefined);
|
|
47
47
|
}
|
|
48
48
|
function TryInferResults(rest, right, result = []) {
|
|
49
|
-
return Guard.
|
|
49
|
+
return Guard.ShiftLeft(rest, (head, tail) => Result.Match(ExtendsLeft({}, head, right), () => TryInferResults(tail, right, [...result, head]), () => undefined), () => result);
|
|
50
50
|
}
|
|
51
51
|
export function InferTupleResult(inferred, name, left, right) {
|
|
52
52
|
const results = TryInferResults(left, right);
|
|
@@ -6,6 +6,8 @@ import { type TOptional } from '../types/_optional.mjs';
|
|
|
6
6
|
import { type TInfer } from '../types/infer.mjs';
|
|
7
7
|
import { type TNever } from '../types/never.mjs';
|
|
8
8
|
import { type TObject } from '../types/object.mjs';
|
|
9
|
+
import { type TRecord } from '../types/record.mjs';
|
|
10
|
+
import { type TUnion } from '../types/union.mjs';
|
|
9
11
|
import { type TExtendsLeft } from './extends_left.mjs';
|
|
10
12
|
import { type TExtendsRight } from './extends_right.mjs';
|
|
11
13
|
import { type TUnionToTuple } from '../engine/helpers/union.mjs';
|
|
@@ -20,6 +22,11 @@ type TExtendsPropertiesComparer<Inferred extends TProperties, Left extends TProp
|
|
|
20
22
|
}, Checked extends boolean = Properties[keyof Right] extends Result.TExtendsTrueLike ? true : false, Extracted extends TProperties = Checked extends true ? TExtractInferredProperties<TUnionToTuple<keyof Properties>, Properties> : {}> = (Checked extends true ? Result.TExtendsTrue<Extracted> : Result.TExtendsFalse);
|
|
21
23
|
type TExtendsProperties<Inferred extends TProperties, Left extends TProperties, Right extends TProperties, Compared extends Result.TResult = TExtendsPropertiesComparer<Inferred, Left, Right>> = (Compared extends Result.TExtendsTrueLike<infer ComparedInferred extends TProperties> ? Result.TExtendsTrue<Memory.TAssign<Inferred, ComparedInferred>> : Result.TExtendsFalse);
|
|
22
24
|
type TExtendsObjectToObject<Inferred extends TProperties, Left extends TProperties, Right extends TProperties> = (TExtendsProperties<Inferred, Left, Right>);
|
|
23
|
-
|
|
25
|
+
type TRecordMergeInferred<Left extends TProperties, Right extends TProperties, Result extends TProperties = {
|
|
26
|
+
[Key in keyof Right]: Key extends keyof Left ? Left[Key] extends TUnion<infer Types extends TSchema[]> ? TUnion<[...Types, Right[Key]]> : TUnion<[Left[Key], Right[Key]]> : Right[Key];
|
|
27
|
+
}> = Result;
|
|
28
|
+
type TExtendsRecordComparer<Properties extends TProperties, Keys extends (keyof Properties)[], Type extends TSchema, Result extends TProperties> = (Keys extends [infer Left extends (keyof Properties), ...infer Right extends (keyof Properties)[]] ? TExtendsLeft<{}, Properties[Left], Type> extends Result.TExtendsTrueLike<infer Inferred extends TProperties> ? TExtendsRecordComparer<Properties, Right, Type, TRecordMergeInferred<Result, Inferred>> : Result.TExtendsFalse : Result.TExtendsTrue<Result>);
|
|
29
|
+
type TExtendsObjectToRecord<Inferred extends TProperties, Properties extends TProperties, _Pattern extends string, Value extends TSchema, Keys extends (keyof Properties)[] = TUnionToTuple<keyof Properties>, Result extends Result.TResult = TExtendsRecordComparer<Properties, Keys, Value, Inferred>> = Result;
|
|
30
|
+
export type TExtendsObject<Inferred extends TProperties, Left extends TProperties, Right extends TSchema> = (Right extends TRecord<infer Pattern extends string, infer Value extends TSchema> ? TExtendsObjectToRecord<Inferred, Left, Pattern, Value> : Right extends TObject<infer Properties extends TProperties> ? TExtendsObjectToObject<Inferred, Left, Properties> : TExtendsRight<Inferred, TObject<Left>, Right>);
|
|
24
31
|
export declare function ExtendsObject<Inferred extends TProperties, Left extends TProperties, Right extends TSchema>(inferred: Inferred, left: Left, right: Right): TExtendsObject<Inferred, Left, Right>;
|
|
25
32
|
export {};
|
|
@@ -7,6 +7,8 @@ import { IsOptional } from '../types/_optional.mjs';
|
|
|
7
7
|
import { IsInfer } from '../types/infer.mjs';
|
|
8
8
|
import { IsNever } from '../types/never.mjs';
|
|
9
9
|
import { IsObject, Object } from '../types/object.mjs';
|
|
10
|
+
import { IsRecord, RecordPattern, RecordValue } from '../types/record.mjs';
|
|
11
|
+
import { Union, IsUnion } from '../types/union.mjs';
|
|
10
12
|
import { ExtendsLeft } from './extends_left.mjs';
|
|
11
13
|
import { ExtendsRight } from './extends_right.mjs';
|
|
12
14
|
import * as Result from './result.mjs';
|
|
@@ -80,8 +82,28 @@ function ExtendsProperties(inferred, left, right) {
|
|
|
80
82
|
function ExtendsObjectToObject(inferred, left, right) {
|
|
81
83
|
return ExtendsProperties(inferred, left, right);
|
|
82
84
|
}
|
|
85
|
+
function RecordMergeInferred(left, right) {
|
|
86
|
+
return Guard.Keys(right).reduce((result, key) => {
|
|
87
|
+
return {
|
|
88
|
+
...result, [key]: Guard.HasPropertyKey(left, key)
|
|
89
|
+
? IsUnion(result[key])
|
|
90
|
+
// @ts-ignore 5.0.4 cannot see `.anyOf`
|
|
91
|
+
? Union([...result[key].anyOf, right[key]])
|
|
92
|
+
: Union([left[key], right[key]])
|
|
93
|
+
: right[key]
|
|
94
|
+
};
|
|
95
|
+
}, left);
|
|
96
|
+
}
|
|
97
|
+
function ExtendsRecordComparer(properties, keys, type, result) {
|
|
98
|
+
return Guard.ShiftLeft(keys, (left, right) => Result.Match(ExtendsLeft({}, properties[left], type), inferred => ExtendsRecordComparer(properties, right, type, RecordMergeInferred(result, inferred)), () => Result.ExtendsFalse()), () => Result.ExtendsTrue(result));
|
|
99
|
+
}
|
|
100
|
+
function ExtendsObjectToRecord(inferred, properties, _pattern, value) {
|
|
101
|
+
const keys = Guard.Keys(properties);
|
|
102
|
+
const result = ExtendsRecordComparer(properties, keys, value, inferred);
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
83
105
|
export function ExtendsObject(inferred, left, right) {
|
|
84
|
-
return (
|
|
85
|
-
? ExtendsObjectToObject(inferred, left, right.properties)
|
|
86
|
-
|
|
106
|
+
return (IsRecord(right) ? ExtendsObjectToRecord(inferred, left, RecordPattern(right), RecordValue(right)) :
|
|
107
|
+
IsObject(right) ? ExtendsObjectToObject(inferred, left, right.properties) :
|
|
108
|
+
ExtendsRight(inferred, Object(left), right));
|
|
87
109
|
}
|
|
@@ -16,12 +16,12 @@ function ParameterCompare(inferred, left, leftRest, right, rightRest) {
|
|
|
16
16
|
);
|
|
17
17
|
}
|
|
18
18
|
function ParameterRight(inferred, left, leftRest, rightRest) {
|
|
19
|
-
return Guard.
|
|
19
|
+
return Guard.ShiftLeft(rightRest, (head, tail) => ParameterCompare(inferred, left, leftRest, head, tail), () => IsOptional(left) // 'right-did-not-have-enough-elements'
|
|
20
20
|
? Result.ExtendsTrue(inferred) // 'ok: left was optional'
|
|
21
21
|
: Result.ExtendsFalse()); // 'fail: left was required'
|
|
22
22
|
}
|
|
23
23
|
function ParametersLeft(inferred, left, rightRest) {
|
|
24
|
-
return Guard.
|
|
24
|
+
return Guard.ShiftLeft(left, (head, tail) => ParameterRight(inferred, head, tail, rightRest), () => Result.ExtendsTrue(inferred)); // 'ok: no-more-elements-in-left'
|
|
25
25
|
}
|
|
26
26
|
export function ExtendsParameters(inferred, left, right) {
|
|
27
27
|
return ParametersLeft(inferred, left, right);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type TSchema } from '../types/schema.mjs';
|
|
2
|
+
import { type TProperties } from '../types/properties.mjs';
|
|
3
|
+
import { type TAny } from '../types/any.mjs';
|
|
4
|
+
import { type TUnknown } from '../types/unknown.mjs';
|
|
5
|
+
import { type TObject } from '../types/object.mjs';
|
|
6
|
+
import { type TRecordPatternToType, type TRecord } from '../types/record.mjs';
|
|
7
|
+
import { type TExtendsLeft } from './extends_left.mjs';
|
|
8
|
+
import * as Result from './result.mjs';
|
|
9
|
+
export type TFromObject<Inferred extends TProperties, Properties extends TProperties> = keyof Properties extends never ? Result.TExtendsTrue<Inferred> : Result.TExtendsFalse;
|
|
10
|
+
type TFromRecord<Inferred extends TProperties, _LeftKey extends TSchema, LeftValue extends TSchema, _RightKey extends TSchema, RightValue extends TSchema> = (TExtendsLeft<Inferred, LeftValue, RightValue>);
|
|
11
|
+
export type TExtendsRecord<Inferred extends TProperties, LeftPattern extends string, LeftValue extends TSchema, Right extends TSchema> = (Right extends TRecord<infer Pattern extends string, infer Value extends TSchema> ? TFromRecord<Inferred, TRecordPatternToType<LeftPattern>, LeftValue, TRecordPatternToType<Pattern>, Value> : Right extends TObject<infer Properties extends TProperties> ? TFromObject<Inferred, Properties> : Right extends TAny ? Result.TExtendsTrue<Inferred> : Right extends TUnknown ? Result.TExtendsTrue<Inferred> : Result.TExtendsFalse);
|
|
12
|
+
export declare function ExtendsRecord<Inferred extends TProperties, Pattern extends string, Value extends TSchema, Right extends TSchema>(inferred: Inferred, leftPattern: Pattern, leftValue: Value, right: Right): TExtendsRecord<Inferred, Pattern, Value, Right>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// deno-fmt-ignore-file
|
|
2
|
+
import { Guard } from '../../guard/index.mjs';
|
|
3
|
+
import { IsAny } from '../types/any.mjs';
|
|
4
|
+
import { IsUnknown } from '../types/unknown.mjs';
|
|
5
|
+
import { IsObject } from '../types/object.mjs';
|
|
6
|
+
import { IsRecord, RecordPatternToType, RecordPattern, RecordValue } from '../types/record.mjs';
|
|
7
|
+
import { ExtendsLeft } from './extends_left.mjs';
|
|
8
|
+
import * as Result from './result.mjs';
|
|
9
|
+
function FromObject(inferred, properties) {
|
|
10
|
+
return (Guard.IsEqual(Guard.Keys(properties).length, 0)
|
|
11
|
+
? Result.ExtendsTrue(inferred)
|
|
12
|
+
: Result.ExtendsFalse());
|
|
13
|
+
}
|
|
14
|
+
function FromRecord(inferred, _leftKey, leftValue, _rightKey, rightValue) {
|
|
15
|
+
return ExtendsLeft(inferred, leftValue, rightValue);
|
|
16
|
+
}
|
|
17
|
+
export function ExtendsRecord(inferred, leftPattern, leftValue, right) {
|
|
18
|
+
return (IsRecord(right) ? FromRecord(inferred, RecordPatternToType(leftPattern), leftValue, RecordPatternToType(RecordPattern(right)), RecordValue(right)) :
|
|
19
|
+
IsObject(right) ? FromObject(inferred, right.properties) :
|
|
20
|
+
IsAny(right) ? Result.ExtendsTrue(inferred) :
|
|
21
|
+
IsUnknown(right) ? Result.ExtendsTrue(inferred) :
|
|
22
|
+
Result.ExtendsFalse());
|
|
23
|
+
}
|
|
@@ -32,10 +32,10 @@ function ElementsLeft(inferred, reversed, leftRest, right, rightRest) {
|
|
|
32
32
|
// Rest Inferrable Right Means we delegate to TInferTupleResult to Generate a Result
|
|
33
33
|
IsInferable(inferable)
|
|
34
34
|
? InferTupleResult(inferred, inferable['name'], ApplyReverse(leftRest, reversed), inferable['type'])
|
|
35
|
-
: Guard.
|
|
35
|
+
: Guard.ShiftLeft(leftRest, (head, tail) => ElementsCompare(inferred, reversed, head, tail, right, rightRest), () => Result.ExtendsFalse()));
|
|
36
36
|
}
|
|
37
37
|
function ElementsRight(inferred, reversed, leftRest, rightRest) {
|
|
38
|
-
return Guard.
|
|
38
|
+
return Guard.ShiftLeft(rightRest, (head, tail) => ElementsLeft(inferred, reversed, leftRest, head, tail), () => Guard.IsEqual(leftRest.length, 0)
|
|
39
39
|
? Result.ExtendsTrue(inferred) // 'Ok: right-empty-and-left-empty'
|
|
40
40
|
: Result.ExtendsFalse()); // 'Fail: right-empty-and-left-not-empty'
|
|
41
41
|
}
|
|
@@ -51,7 +51,7 @@ function ExtendsTupleToArray(inferred, left, right) {
|
|
|
51
51
|
const inferrable = TryInferable(right);
|
|
52
52
|
return (IsInferable(inferrable)
|
|
53
53
|
? InferUnionResult(inferred, inferrable['name'], left, inferrable['type'])
|
|
54
|
-
: Guard.
|
|
54
|
+
: Guard.ShiftLeft(left, (head, tail) => Result.Match(ExtendsLeft(inferred, head, right), inferred => ExtendsTupleToArray(inferred, tail, right), () => Result.ExtendsFalse()), () => Result.ExtendsTrue(inferred)));
|
|
55
55
|
}
|
|
56
56
|
export function ExtendsTuple(inferred, left, right) {
|
|
57
57
|
const instantiatedLeft = InstantiateElements(inferred, State([], []), left);
|
|
@@ -8,10 +8,10 @@ import * as Result from './result.mjs';
|
|
|
8
8
|
// ----------------------------------------------------------------------------
|
|
9
9
|
import { IsInferable, TryInferable, InferUnionResult } from './inference.mjs';
|
|
10
10
|
function ExtendsUnionSome(inferred, type, unionTypes) {
|
|
11
|
-
return Guard.
|
|
11
|
+
return Guard.ShiftLeft(unionTypes, (head, tail) => Result.Match(ExtendsLeft(inferred, type, head), inferred => Result.ExtendsTrue(inferred), () => ExtendsUnionSome(inferred, type, tail)), () => Result.ExtendsFalse());
|
|
12
12
|
}
|
|
13
13
|
function ExtendsUnionLeft(inferred, left, right) {
|
|
14
|
-
return Guard.
|
|
14
|
+
return Guard.ShiftLeft(left, (head, tail) => Result.Match(ExtendsUnionSome(inferred, head, right), inferred => ExtendsUnionLeft(inferred, tail, right), () => Result.ExtendsFalse()), () => Result.ExtendsTrue(inferred));
|
|
15
15
|
}
|
|
16
16
|
export function ExtendsUnion(inferred, left, right) {
|
|
17
17
|
const inferrable = TryInferable(right);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { IsArray, IsEqual, IsString,
|
|
1
|
+
export { IsArray, IsEqual, IsString, ShiftLeft } from '../../../../guard/guard.mjs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// deno-coverage-ignore-start - parsebox tested
|
|
2
|
-
export { IsArray, IsEqual, IsString,
|
|
2
|
+
export { IsArray, IsEqual, IsString, ShiftLeft } from '../../../../guard/guard.mjs';
|
|
3
3
|
// ------------------------------------------------------------------
|
|
4
4
|
// Internal Guards to ensure Token is portable.
|
|
5
5
|
// ------------------------------------------------------------------
|
|
@@ -12,7 +12,7 @@ export function Take(variants, input) {
|
|
|
12
12
|
// ----------------------------------------------------------------
|
|
13
13
|
// Symmetric
|
|
14
14
|
// ----------------------------------------------------------------
|
|
15
|
-
// return Guard.
|
|
15
|
+
// return Guard.ShiftLeft(variants, (valueLeft, valueRight) =>
|
|
16
16
|
// Match(TakeVariant(valueLeft, input), (take, rest) =>
|
|
17
17
|
// [take, rest],
|
|
18
18
|
// () => Take(valueRight, input)),
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// deno-coverage-ignore-start - parsebox tested
|
|
2
2
|
// deno-fmt-ignore-file
|
|
3
3
|
import { Match } from './internal/match.mjs';
|
|
4
|
-
import { IsEqual,
|
|
4
|
+
import { IsEqual, ShiftLeft } from './internal/guard.mjs';
|
|
5
5
|
function TakeOne(input) {
|
|
6
6
|
const result = IsEqual(input, '') ? [] : [input.slice(0, 1), input.slice(1)];
|
|
7
7
|
return result;
|
|
8
8
|
}
|
|
9
9
|
function IsInputMatchSentinal(end, input) {
|
|
10
|
-
return
|
|
10
|
+
return ShiftLeft(end, (left, right) => input.startsWith(left)
|
|
11
11
|
? true
|
|
12
12
|
: IsInputMatchSentinal(right, input), () => false);
|
|
13
13
|
}
|
|
@@ -31,15 +31,21 @@ export declare function RecordDeferred<Key extends TSchema, Value extends TSchem
|
|
|
31
31
|
export declare function Record<Key extends TSchema, Value extends TSchema>(key: Key, value: Value, options?: TObjectOptions): TRecordAction<Key, Value>;
|
|
32
32
|
/** Creates a Record type from regular expression pattern. */
|
|
33
33
|
export declare function RecordFromPattern<Pattern extends string, Value extends TSchema>(key: Pattern, value: Value): TRecord<Pattern, Value>;
|
|
34
|
-
/**
|
|
34
|
+
/** Transforms a Record Pattern to a Type */
|
|
35
|
+
export type TRecordPatternToType<Pattern extends string, Result extends TSchema = (Pattern extends typeof StringKey ? TString : Pattern extends typeof IntegerKey ? TInteger : Pattern extends typeof NumberKey ? TNumber : TTemplateLiteralDecodeUnsafe<Pattern>)> = Result;
|
|
36
|
+
/** Transforms a Record Pattern to a Type */
|
|
37
|
+
export declare function RecordPatternToType<Pattern extends string>(pattern: Pattern): TRecordPatternToType<Pattern>;
|
|
38
|
+
/** Extracts the Pattern from a Record type */
|
|
35
39
|
export type TRecordPattern<Type extends TRecord, Result extends string = Extract<keyof Type['patternProperties'], string>> = Result;
|
|
36
|
-
/**
|
|
40
|
+
/** Extracts the Pattern from a Record type */
|
|
37
41
|
export declare function RecordPattern<Type extends TRecord>(type: Type): TRecordPattern<Type>;
|
|
38
|
-
/**
|
|
39
|
-
export type TRecordKey<Type extends TRecord, Pattern extends string = TRecordPattern<Type>, Result extends TSchema =
|
|
40
|
-
/**
|
|
42
|
+
/** Extracts the Key from a Record type */
|
|
43
|
+
export type TRecordKey<Type extends TRecord, Pattern extends string = TRecordPattern<Type>, Result extends TSchema = TRecordPatternToType<Pattern>> = Result;
|
|
44
|
+
/** Extracts the Key from a Record type */
|
|
41
45
|
export declare function RecordKey<Type extends TRecord>(type: Type): TRecordKey<Type>;
|
|
46
|
+
/** Extracts the Value from a Record type */
|
|
42
47
|
export type TRecordValue<Type extends TRecord, Result extends TSchema = Type['patternProperties'][TRecordPattern<Type>]> = Result;
|
|
48
|
+
/** Extracts the Value from a Record type */
|
|
43
49
|
export declare function RecordValue<Type extends TRecord>(type: Type): TRecordValue<Type>;
|
|
44
50
|
export declare function IsRecord(value: unknown): value is TRecord;
|
|
45
51
|
export declare function RecordOptions(type: TRecord): TObjectOptions;
|
|
@@ -30,19 +30,25 @@ export function Record(key, value, options = {}) {
|
|
|
30
30
|
export function RecordFromPattern(key, value) {
|
|
31
31
|
return CreateRecord(key, value);
|
|
32
32
|
}
|
|
33
|
-
/**
|
|
33
|
+
/** Transforms a Record Pattern to a Type */
|
|
34
|
+
export function RecordPatternToType(pattern) {
|
|
35
|
+
const result = (Guard.IsEqual(pattern, StringKey) ? String() :
|
|
36
|
+
Guard.IsEqual(pattern, IntegerKey) ? Integer() :
|
|
37
|
+
Guard.IsEqual(pattern, NumberKey) ? Number() :
|
|
38
|
+
TemplateLiteralDecodeUnsafe(pattern));
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
/** Extracts the Pattern from a Record type */
|
|
34
42
|
export function RecordPattern(type) {
|
|
35
43
|
return Guard.Keys(type.patternProperties)[0];
|
|
36
44
|
}
|
|
37
|
-
/**
|
|
45
|
+
/** Extracts the Key from a Record type */
|
|
38
46
|
export function RecordKey(type) {
|
|
39
47
|
const pattern = RecordPattern(type);
|
|
40
|
-
const result = (
|
|
41
|
-
Guard.IsEqual(pattern, IntegerKey) ? Integer() :
|
|
42
|
-
Guard.IsEqual(pattern, NumberKey) ? Number() :
|
|
43
|
-
TemplateLiteralDecodeUnsafe(pattern));
|
|
48
|
+
const result = RecordPatternToType(pattern);
|
|
44
49
|
return result;
|
|
45
50
|
}
|
|
51
|
+
/** Extracts the Value from a Record type */
|
|
46
52
|
export function RecordValue(type) {
|
|
47
53
|
return type.patternProperties[RecordPattern(type)];
|
|
48
54
|
}
|
|
@@ -26,7 +26,7 @@ function DeterministicCompare(left, right) {
|
|
|
26
26
|
// ------------------------------------------------------------------
|
|
27
27
|
/** Deterministically sorts schemas by structural relationship (narrow to broad) */
|
|
28
28
|
export function UnionPrioritySort(types, order = 1) {
|
|
29
|
-
return types.sort((left, right) => {
|
|
29
|
+
return [...types].sort((left, right) => {
|
|
30
30
|
const result = Compare(left, right);
|
|
31
31
|
return (Guard.IsEqual(result, 'disjoint') ? DeterministicCompare(left, right) :
|
|
32
32
|
Guard.IsEqual(result, 'right-inside') ? 1 :
|