Skip to content

Commit

Permalink
Reimplement Index Types
Browse files Browse the repository at this point in the history
  • Loading branch information
sinclairzx81 committed Nov 23, 2023
1 parent 1226205 commit aef8a54
Showing 1 changed file with 66 additions and 55 deletions.
121 changes: 66 additions & 55 deletions src/typebox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand All @@ -1692,8 +1703,8 @@ export namespace TypeExtends {
// --------------------------------------------------------------------------
// StructuralRight
// --------------------------------------------------------------------------
// prettier-ignore
function IsStructuralRight(right: TSchema): boolean {
// prettier-ignore
return (
TypeGuard.TNever(right) ||
TypeGuard.TIntersect(right) ||
Expand All @@ -1702,54 +1713,54 @@ 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
// --------------------------------------------------------------------------
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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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. */
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 }
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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<string> {
if (buffer.length === 1) return yield* buffer[0]
Expand Down Expand Up @@ -2938,13 +2949,13 @@ export namespace TemplateLiteralDslParser {
// TransformBuilder
// ---------------------------------------------------------------------
export class TransformDecodeBuilder<T extends TSchema> {
constructor(private readonly schema: T) {}
constructor(private readonly schema: T) { }
public Decode<U extends unknown, D extends TransformFunction<StaticDecode<T>, U>>(decode: D): TransformEncodeBuilder<T, D> {
return new TransformEncodeBuilder(this.schema, decode)
}
}
export class TransformEncodeBuilder<T extends TSchema, D extends TransformFunction> {
constructor(private readonly schema: T, private readonly decode: D) {}
constructor(private readonly schema: T, private readonly decode: D) { }
public Encode<E extends TransformFunction<ReturnType<D>, StaticDecode<T>>>(encode: E): TTransform<T, ReturnType<D>> {
const schema = TypeClone.Type(this.schema)
// prettier-ignore
Expand All @@ -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<T>(schema: Omit<T, 'static' | 'params'>): T {
Expand Down

0 comments on commit aef8a54

Please sign in to comment.