From aef8a54eeff7e4130c92070b52827fe65ac551df Mon Sep 17 00:00:00 2001 From: sinclair Date: Thu, 23 Nov 2023 16:00:28 +0900 Subject: [PATCH] Reimplement Index Types --- src/typebox.ts | 121 +++++++++++++++++++++++++++---------------------- 1 file changed, 66 insertions(+), 55 deletions(-) diff --git a/src/typebox.ts b/src/typebox.ts index 3dbbbe683..fe556aacd 100644 --- a/src/typebox.ts +++ b/src/typebox.ts @@ -1174,7 +1174,7 @@ export namespace ValueGuard { // -------------------------------------------------------------------------- // TypeGuard // -------------------------------------------------------------------------- -export class TypeGuardUnknownTypeError extends TypeBoxError {} +export class TypeGuardUnknownTypeError extends TypeBoxError { } /** Provides functions to test if JavaScript values are TypeBox types */ export namespace TypeGuard { function IsPattern(value: unknown): value is string { @@ -1653,24 +1653,35 @@ export namespace TypeGuard { // -------------------------------------------------------------------------- // ExtendsUndefined // -------------------------------------------------------------------------- -/** Fast undefined check used for properties of type undefined */ +/** Fast undefined check */ export namespace ExtendsUndefined { + export function TIntersect(schema: TIntersect) { + return schema.allOf.every(schema => Check(schema)) + } + export function TUnion(schema: TUnion) { + return schema.anyOf.some(schema => Check(schema)) + } + export function TNot(schema: TNot) { + return !Check(schema.not) + } + export function TUndefined(schema: TUndefined) { + return true + } + // prettier-ignore export function Check(schema: TSchema): boolean { - return schema[Kind] === 'Intersect' - ? (schema as TIntersect).allOf.every((schema) => Check(schema)) - : schema[Kind] === 'Union' - ? (schema as TUnion).anyOf.some((schema) => Check(schema)) - : schema[Kind] === 'Undefined' - ? true - : schema[Kind] === 'Not' - ? !Check(schema.not) - : false + switch (true) { + case schema[Kind] === 'Intersect': return TIntersect(schema as TIntersect) + case schema[Kind] === 'Union': return TUnion(schema as TUnion) + case schema[Kind] === 'Not': return TNot(schema as TNot) + case schema[Kind] === 'Undefined': return TUndefined(schema as TUndefined) + default: return false + } } } // -------------------------------------------------------------------------- // TypeExtends // -------------------------------------------------------------------------- -export class TypeExtendsError extends TypeBoxError {} +export class TypeExtendsError extends TypeBoxError { } export enum TypeExtendsResult { Union, True, @@ -1692,8 +1703,8 @@ export namespace TypeExtends { // -------------------------------------------------------------------------- // StructuralRight // -------------------------------------------------------------------------- + // prettier-ignore function IsStructuralRight(right: TSchema): boolean { - // prettier-ignore return ( TypeGuard.TNever(right) || TypeGuard.TIntersect(right) || @@ -1702,16 +1713,16 @@ export namespace TypeExtends { TypeGuard.TAny(right) ) } + // prettier-ignore function StructuralRight(left: TSchema, right: TSchema) { - // prettier-ignore - return ( - TypeGuard.TNever(right) ? TNeverRight(left, right) : - TypeGuard.TIntersect(right) ? TIntersectRight(left, right) : - TypeGuard.TUnion(right) ? TUnionRight(left, right) : - TypeGuard.TUnknown(right) ? TUnknownRight(left, right) : - TypeGuard.TAny(right) ? TAnyRight(left, right) : - Throw('StructuralRight') - ) + switch (true) { + case TypeGuard.TNever(right): return TNeverRight(left, right) + case TypeGuard.TIntersect(right): return TIntersectRight(left, right) + case TypeGuard.TUnion(right): return TUnionRight(left, right) + case TypeGuard.TUnknown(right): return TUnknownRight(left, right) + case TypeGuard.TAny(right): return TAnyRight(left, right) + default: Throw('StructuralRight') + } } // -------------------------------------------------------------------------- // Any @@ -1719,37 +1730,37 @@ export namespace TypeExtends { function TAnyRight(left: TSchema, right: TAny) { return TypeExtendsResult.True } + // prettier-ignore function TAny(left: TAny, right: TSchema) { - // prettier-ignore - return ( - TypeGuard.TIntersect(right) ? TIntersectRight(left, right) : - (TypeGuard.TUnion(right) && right.anyOf.some((schema) => TypeGuard.TAny(schema) || TypeGuard.TUnknown(schema))) ? TypeExtendsResult.True : - TypeGuard.TUnion(right) ? TypeExtendsResult.Union : - TypeGuard.TUnknown(right) ? TypeExtendsResult.True : - TypeGuard.TAny(right) ? TypeExtendsResult.True : - TypeExtendsResult.Union - ) + switch (true) { + case TypeGuard.TIntersect(right): return TIntersectRight(left, right) + case (TypeGuard.TUnion(right) && right.anyOf.some((schema) => TypeGuard.TAny(schema) || TypeGuard.TUnknown(schema))): return TypeExtendsResult.True + case TypeGuard.TUnion(right): return TypeExtendsResult.Union + case TypeGuard.TUnknown(right): return TypeExtendsResult.True + case TypeGuard.TAny(right): return TypeExtendsResult.True + default: return TypeExtendsResult.Union + } } // -------------------------------------------------------------------------- // Array // -------------------------------------------------------------------------- + // prettier-ignore function TArrayRight(left: TSchema, right: TArray) { - // prettier-ignore - return ( - TypeGuard.TUnknown(left) ? TypeExtendsResult.False : - TypeGuard.TAny(left) ? TypeExtendsResult.Union : - TypeGuard.TNever(left) ? TypeExtendsResult.True : - TypeExtendsResult.False - ) + switch (true) { + case TypeGuard.TUnknown(left): return TypeExtendsResult.False + case TypeGuard.TAny(left): return TypeExtendsResult.Union + case TypeGuard.TNever(left): return TypeExtendsResult.True + default: return TypeExtendsResult.False + } } + // prettier-ignore function TArray(left: TArray, right: TSchema) { - // prettier-ignore - return ( - TypeGuard.TObject(right) && IsObjectArrayLike(right) ? TypeExtendsResult.True : - IsStructuralRight(right) ? StructuralRight(left, right) : - !TypeGuard.TArray(right) ? TypeExtendsResult.False : - IntoBooleanResult(Visit(left.items, right.items)) - ) + switch (true) { + case TypeGuard.TObject(right) && IsObjectArrayLike(right): return TypeExtendsResult.True + case IsStructuralRight(right): return StructuralRight(left, right) + case !TypeGuard.TArray(right): return TypeExtendsResult.False + default: return IntoBooleanResult(Visit(left.items, right.items)) + } } // -------------------------------------------------------------------------- // AsyncIterator @@ -2572,7 +2583,7 @@ export namespace Accessor { return IsUnionOptional(schema.anyOf) ? Type.Optional(Type.Union(OptionalUnwrap(schema.anyOf))) : schema } function ResolveOptional(schema: TSchema) { - switch(true) { + switch (true) { case schema[Kind] === 'Intersect': return ResolveIntersect(schema as TIntersect) case schema[Kind] === 'Union': return ResolveUnion(schema as TUnion) default: return schema @@ -2601,7 +2612,7 @@ export namespace Accessor { return element } function Visit(schema: TSchema, key: string): TSchema { - switch(true) { + switch (true) { case schema[Kind] === 'Intersect': return TIntersect(schema as TIntersect, key) case schema[Kind] === 'Union': return TUnion(schema as TUnion, key) case schema[Kind] === 'Object': return TObject(schema as TObject, key) @@ -2617,7 +2628,7 @@ export namespace Accessor { // -------------------------------------------------------------------------- // KeyArrayResolver // -------------------------------------------------------------------------- -export class KeyArrayResolverError extends TypeBoxError {} +export class KeyArrayResolverError extends TypeBoxError { } // prettier-ignore export namespace KeyArrayResolver { /** Resolves an array of string[] keys from the given schema or array type. */ @@ -2654,7 +2665,7 @@ export namespace UnionResolver { // -------------------------------------------------------------------------- // TemplateLiteralPattern // -------------------------------------------------------------------------- -export class TemplateLiteralPatternError extends TypeBoxError {} +export class TemplateLiteralPatternError extends TypeBoxError { } export namespace TemplateLiteralPattern { function Throw(message: string): never { throw new TemplateLiteralPatternError(message) @@ -2695,7 +2706,7 @@ export namespace TemplateLiteralResolver { // -------------------------------------------------------------------------------------- // TemplateLiteralParser // -------------------------------------------------------------------------------------- -export class TemplateLiteralParserError extends TypeBoxError {} +export class TemplateLiteralParserError extends TypeBoxError { } export namespace TemplateLiteralParser { export type Expression = And | Or | Const export type Const = { type: 'const'; const: string } @@ -2811,7 +2822,7 @@ export namespace TemplateLiteralParser { // -------------------------------------------------------------------------------------- // TemplateLiteralFinite // -------------------------------------------------------------------------------------- -export class TemplateLiteralFiniteError extends TypeBoxError {} +export class TemplateLiteralFiniteError extends TypeBoxError { } export namespace TemplateLiteralFinite { function Throw(message: string): never { throw new TemplateLiteralFiniteError(message) @@ -2854,7 +2865,7 @@ export namespace TemplateLiteralFinite { // -------------------------------------------------------------------------------------- // TemplateLiteralGenerator // -------------------------------------------------------------------------------------- -export class TemplateLiteralGeneratorError extends TypeBoxError {} +export class TemplateLiteralGeneratorError extends TypeBoxError { } export namespace TemplateLiteralGenerator { function* Reduce(buffer: string[][]): IterableIterator { if (buffer.length === 1) return yield* buffer[0] @@ -2938,13 +2949,13 @@ export namespace TemplateLiteralDslParser { // TransformBuilder // --------------------------------------------------------------------- export class TransformDecodeBuilder { - constructor(private readonly schema: T) {} + constructor(private readonly schema: T) { } public Decode, U>>(decode: D): TransformEncodeBuilder { return new TransformEncodeBuilder(this.schema, decode) } } export class TransformEncodeBuilder { - constructor(private readonly schema: T, private readonly decode: D) {} + constructor(private readonly schema: T, private readonly decode: D) { } public Encode, StaticDecode>>(encode: E): TTransform> { const schema = TypeClone.Type(this.schema) // prettier-ignore @@ -2968,7 +2979,7 @@ let TypeOrdinal = 0 // -------------------------------------------------------------------------- // TypeBuilder // -------------------------------------------------------------------------- -export class TypeBuilderError extends TypeBoxError {} +export class TypeBuilderError extends TypeBoxError { } export class TypeBuilder { /** `[Internal]` Creates a schema without `static` and `params` types */ protected Create(schema: Omit): T {