Skip to content

Commit

Permalink
Type and Value Optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
sinclairzx81 committed Apr 25, 2024
1 parent 130c520 commit 4836aae
Show file tree
Hide file tree
Showing 163 changed files with 3,812 additions and 426 deletions.
58 changes: 18 additions & 40 deletions example/index.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,18 @@
import { TypeSystem } from '@sinclair/typebox/system'
import { TypeCompiler } from '@sinclair/typebox/compiler'
import { Value, ValuePointer } from '@sinclair/typebox/value'
import { Type, TypeGuard, Kind, Static, TSchema } from '@sinclair/typebox'

// -----------------------------------------------------------
// Create: Type
// -----------------------------------------------------------

const T = Type.Object({
x: Type.Number(),
y: Type.Number(),
z: Type.Number(),
})

type T = Static<typeof T>

console.log(T)

// -----------------------------------------------------------
// Create: Value
// -----------------------------------------------------------

const V = Value.Create(T)

console.log(V)

// -----------------------------------------------------------
// Compile: Type
// -----------------------------------------------------------

const C = TypeCompiler.Compile(T)

console.log(C.Code())

// -----------------------------------------------------------
// Check: Value
// -----------------------------------------------------------

console.log(C.Check(V))
import { Type, TypeGuard } from '@sinclair/typebox'
import { Value } from '@sinclair/typebox/value'

const K = Type.TemplateLiteral('prop${0|1}${0|1}${0|1}${0|1}${0|1}${0|1}')
const T = Type.Mapped(K, (_) =>
Type.Object({
x: Type.Number(),
y: Type.Number(),
z: Type.Number(),
}),
)

const S = Date.now()
for (let i = 0; i < 1000; i++) {
Type.Composite([T, T, T])
}

console.log(Date.now() - S)
2 changes: 1 addition & 1 deletion src/type/awaited/awaited.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { CloneType } from '../clone/type'
// ------------------------------------------------------------------
// TypeGuard
// ------------------------------------------------------------------
import { IsIntersect, IsUnion, IsPromise } from '../guard/type'
import { IsIntersect, IsUnion, IsPromise } from '../guard/kind'
// ------------------------------------------------------------------
// FromRest
// ------------------------------------------------------------------
Expand Down
11 changes: 8 additions & 3 deletions src/type/clone/value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@ function RegExpType(value: RegExp) {
return new RegExp(value.source, value.flags)
}
function ObjectType(value: Record<keyof any, unknown>) {
const clonedProperties = Object.getOwnPropertyNames(value).reduce((acc, key) => ({ ...acc, [key]: Visit(value[key]) }), {})
const clonedSymbols = Object.getOwnPropertySymbols(value).reduce((acc, key) => ({ ...acc, [key]: Visit(value[key as any]) }), {})
return { ...clonedProperties, ...clonedSymbols }
const result = {} as Record<PropertyKey, unknown>
for (const key of Object.getOwnPropertyNames(value)) {
result[key] = Visit(value[key])
}
for (const key of Object.getOwnPropertySymbols(value)) {
result[key] = Visit(value[key])
}
return result
}
// prettier-ignore
function Visit(value: unknown): any {
Expand Down
23 changes: 12 additions & 11 deletions src/type/composite/composite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { SetDistinct, TSetDistinct } from '../sets/index'
// ------------------------------------------------------------------
// TypeGuard
// ------------------------------------------------------------------
import { IsNever } from '../guard/type'
import { IsNever } from '../guard/kind'
// ------------------------------------------------------------------
// CompositeKeys
// ------------------------------------------------------------------
Expand All @@ -50,9 +50,9 @@ type TCompositeKeys<T extends TSchema[], Acc extends PropertyKey[] = []> = (
)
// prettier-ignore
function CompositeKeys<T extends TSchema[]>(T: [...T]): TCompositeKeys<T> {
return SetDistinct(T.reduce((Acc, L) => {
return ([...Acc, ...KeyOfPropertyKeys(L)]) as never
}, [])) as never
const Acc = [] as PropertyKey[]
for(const L of T) Acc.push(...KeyOfPropertyKeys(L))
return SetDistinct(Acc) as never
}
// ------------------------------------------------------------------
// FilterNever
Expand Down Expand Up @@ -80,9 +80,9 @@ type TCompositeProperty<T extends TSchema[], K extends PropertyKey, Acc extends
)
// prettier-ignore
function CompositeProperty<T extends TSchema[], K extends PropertyKey>(T: [...T], K: K): TCompositeProperty<T, K> {
return FilterNever(T.reduce((Acc, L) => {
return [...Acc, ...IndexFromPropertyKeys(L, [K])] as never
}, [])) as never
const Acc = [] as TSchema[]
for(const L of T) Acc.push(...IndexFromPropertyKeys(L, [K]))
return FilterNever(Acc) as never
}
// ------------------------------------------------------------------
// CompositeProperties
Expand All @@ -95,9 +95,11 @@ type TCompositeProperties<T extends TSchema[], K extends PropertyKey[], Acc = {}
)
// prettier-ignore
function CompositeProperties<T extends TSchema[], K extends PropertyKey[] = []>(T: [...T], K: [...K]): TCompositeProperties<T, K> {
return K.reduce((Acc, L) => {
return { ...Acc, [L]: IntersectEvaluated(CompositeProperty(T, L)) }
}, {}) as never
const Acc = {} as never
for(const L of K) {
Acc[L] = IntersectEvaluated(CompositeProperty(T, L))
}
return Acc
}
// ------------------------------------------------------------------
// Composite
Expand All @@ -111,7 +113,6 @@ type TCompositeEvaluate<
> = R
// prettier-ignore
export type TComposite<T extends TSchema[]> = TCompositeEvaluate<T>

// prettier-ignore
export function Composite<T extends TSchema[]>(T: [...T], options: ObjectOptions = {}): TComposite<T> {
const K = CompositeKeys(T)
Expand Down
6 changes: 3 additions & 3 deletions src/type/const/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ type TFromProperties<T extends Record<PropertyKey, unknown>> = {
}
// prettier-ignore
function FromProperties<T extends Record<PropertyKey, unknown>>(value: T): TFromProperties<T> {
return globalThis.Object.getOwnPropertyNames(value).reduce((acc, key) => {
return { ...acc, [key]: Readonly(FromValue(value[key], false)) }
}, {} as TProperties) as unknown as TFromProperties<T>
const Acc = {} as TProperties
for(const K of globalThis.Object.getOwnPropertyNames(value)) Acc[K] = Readonly(FromValue(value[K], false))
return Acc as never
}
// ------------------------------------------------------------------
// ConditionalReadonly - Only applied if not root
Expand Down
14 changes: 8 additions & 6 deletions src/type/deref/deref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import { IsUndefined } from '../guard/value'
// ------------------------------------------------------------------
// TypeGuard
// ------------------------------------------------------------------
import { IsConstructor, IsFunction, IsIntersect, IsUnion, IsTuple, IsArray, IsObject, IsPromise, IsAsyncIterator, IsIterator, IsRef } from '../guard/type'
import { IsConstructor, IsFunction, IsIntersect, IsUnion, IsTuple, IsArray, IsObject, IsPromise, IsAsyncIterator, IsIterator, IsRef } from '../guard/kind'
// ------------------------------------------------------------------
// FromRest
// ------------------------------------------------------------------
Expand All @@ -56,8 +56,8 @@ export type TFromRest<T extends TSchema[], Acc extends TSchema[] = []> = (
? TFromRest<R, [...Acc, TDeref<L>]>
: Acc
)
function FromRest(schema: TSchema[], references: TSchema[]) {
return schema.map((schema) => Deref(schema, references))
function FromRest<T extends TSchema[]>(schema: [...T], references: TSchema[]): TFromRest<T> {
return schema.map((schema) => Deref(schema, references)) as never
}
// ------------------------------------------------------------------
// FromProperties
Expand All @@ -68,9 +68,11 @@ type FromProperties<T extends TProperties> = Evaluate<{
}>
// prettier-ignore
function FromProperties(properties: TProperties, references: TSchema[]) {
return globalThis.Object.getOwnPropertyNames(properties).reduce((acc, key) => {
return {...acc, [key]: Deref(properties[key], references) }
}, {} as TProperties)
const Acc = {} as TProperties
for(const K of globalThis.Object.getOwnPropertyNames(properties)) {
Acc[K] = Deref(properties[K], references)
}
return Acc as never
}
// prettier-ignore
function FromConstructor(schema: TConstructor, references: TSchema[]) {
Expand Down
6 changes: 3 additions & 3 deletions src/type/exclude/exclude-from-mapped-result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ function FromProperties<
P extends TProperties,
T extends TSchema
>(P: P, U: T): TFromProperties<P, T> {
return globalThis.Object.getOwnPropertyNames(P).reduce((Acc, K2) => {
return {...Acc, [K2]: Exclude(P[K2], U) }
}, {}) as TFromProperties<P, T>
const Acc = {} as TProperties
for(const K2 of globalThis.Object.getOwnPropertyNames(P)) Acc[K2] = Exclude(P[K2], U)
return Acc as never
}
// ------------------------------------------------------------------
// FromMappedResult
Expand Down
2 changes: 1 addition & 1 deletion src/type/exclude/exclude.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import { ExcludeFromTemplateLiteral, type TExcludeFromTemplateLiteral } from './
// ------------------------------------------------------------------
// TypeGuard
// ------------------------------------------------------------------
import { IsMappedResult, IsTemplateLiteral, IsUnion } from '../guard/type'
import { IsMappedResult, IsTemplateLiteral, IsUnion } from '../guard/kind'
// ------------------------------------------------------------------
// ExcludeRest
// ------------------------------------------------------------------
Expand Down
6 changes: 3 additions & 3 deletions src/type/extends/extends-from-mapped-result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ function FromProperties<
True extends TSchema,
False extends TSchema
>(P: P, Right: Right, True: True, False: False, options: SchemaOptions): TFromProperties<P, Right, True, False> {
return globalThis.Object.getOwnPropertyNames(P).reduce((Acc, K2) => {
return {...Acc, [K2]: Extends(P[K2], Right, True, False, options) }
}, {}) as TFromProperties<P, Right, True, False>
const Acc = {} as TProperties
for(const K2 of globalThis.Object.getOwnPropertyNames(P)) Acc[K2] = Extends(P[K2], Right, True, False, options)
return Acc as never
}
// ------------------------------------------------------------------
// FromMappedResult
Expand Down
2 changes: 1 addition & 1 deletion src/type/extends/extends.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { ExtendsFromMappedResult, type TExtendsFromMappedResult } from './extend
// ------------------------------------------------------------------
// TypeGuard
// ------------------------------------------------------------------
import { IsMappedKey, IsMappedResult } from '../guard/type'
import { IsMappedKey, IsMappedResult } from '../guard/kind'

// prettier-ignore
type TExtendsResolve<L extends TSchema, R extends TSchema, T extends TSchema, U extends TSchema> = (
Expand Down
6 changes: 3 additions & 3 deletions src/type/extract/extract-from-mapped-result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ function FromProperties<
P extends TProperties,
T extends TSchema
>(P: P, T: T): TFromProperties<P, T> {
return globalThis.Object.getOwnPropertyNames(P).reduce((Acc, K2) => {
return {...Acc, [K2]: Extract(P[K2], T) }
}, {}) as TFromProperties<P, T>
const Acc = {} as TProperties
for(const K2 of globalThis.Object.getOwnPropertyNames(P)) Acc[K2] = Extract(P[K2], T)
return Acc as never
}
// ------------------------------------------------------------------
// FromMappedResult
Expand Down
2 changes: 1 addition & 1 deletion src/type/extract/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import { ExtractFromTemplateLiteral, type TExtractFromTemplateLiteral } from './
// ------------------------------------------------------------------
// TypeGuard
// ------------------------------------------------------------------
import { IsMappedResult, IsTemplateLiteral, IsUnion } from '../guard/type'
import { IsMappedResult, IsTemplateLiteral, IsUnion } from '../guard/kind'

// ------------------------------------------------------------------
// ExtractRest
Expand Down
1 change: 1 addition & 0 deletions src/type/guard/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/

export * as KindGuard from './kind'
export * as TypeGuard from './type'
export * as ValueGuard from './value'

0 comments on commit 4836aae

Please sign in to comment.