Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
sinclairzx81 committed Nov 16, 2024
1 parent 8596282 commit c76f2cf
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 148 deletions.
49 changes: 26 additions & 23 deletions example/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Type, TypeGuard, Kind, Static, TSchema } from '@sinclair/typebox'
// - Partial (Computed)
// - Pick (Computed)
// - Omit (Computed)
// - Required
// - Required (Computed)
// - KeyOf

//
Expand All @@ -25,27 +25,30 @@ import { Type, TypeGuard, Kind, Static, TSchema } from '@sinclair/typebox'

const M = Parse('string')

// const Module = Parse(`module {
// type A = {
// x: number
// y: number
// z: number
// }

// type K = 'z' | 'y'

// type T = Partial<Pick<A, K>>
// }`)

const Module = Type.Module({
A: Type.Object({
x: Type.Number(),
y: Type.Number(),
z: Type.Number(),
}),
K: Type.Union([Type.Literal('z'), Type.Literal('y')]),
T: Type.Partial(Type.Omit(Type.Ref('A'), Type.Ref('K'))),
})
const Module = Parse(`module {
type A = {
x: number
y: number
z: number
}
type T = Required<Pick<A, 'x'>> &
Partial<Omit<A, 'x'>>
}`)

// const Module = Type.Module({
// A: Type.Partial(Type.Object({
// x: Type.Number(),
// y: Type.Number(),
// z: Type.Number(),
// })),
// T: Type.Intersect([
// Type.Required(Type.Pick(Type.Ref('A'), ['x'])),
// Type.Partial(Type.Omit(Type.Ref('A'), ['x'])),
// ])
// })

const AA = Type.Required(Type.Pick(Type.Ref('A'), ['x']))

const T = Module.Import('T')

Expand All @@ -57,4 +60,4 @@ type A = Static<typeof T>

// Ok(T, { nodes: [{ nodes: [{ nodes: [] }, { nodes: [] }] }] })

const A = Type.Omit(Type.String(), Type.Ref('A'))
const A = Type.Omit(Type.String(), Type.Ref('A'))
2 changes: 1 addition & 1 deletion src/syntax/static.ts
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ type Partial = Static.Tuple<[
// prettier-ignore
interface RequiredMapping extends Static.IMapping {
output: this['input'] extends ['Required', LAngle, infer Type extends Types.TSchema, RAngle]
? Types.TPartial<Type>
? Types.TRequired<Type>
: never
}
// prettier-ignore
Expand Down
28 changes: 21 additions & 7 deletions src/type/module/compute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import { Pick, type TPick } from '../pick/index'
import { Never, type TNever } from '../never/index'
import { Partial, TPartial } from '../partial/index'
import { Ref, type TRef } from '../ref/index'
import { Required, TRequired, TRequiredRef } from '../required/index'
import { Required, TRequired } from '../required/index'
import { Tuple, type TTuple } from '../tuple/index'
import { Union, type TUnion, type TUnionEvaluated } from '../union/index'

Expand All @@ -54,13 +54,14 @@ import { Union, type TUnion, type TUnionEvaluated } from '../union/index'
// ------------------------------------------------------------------
import * as KindGuard from '../guard/kind'


// ------------------------------------------------------------------
// Deref
// DerefParameters
//
// Dereferences TComputed parameters. It is important to note that
// dereferencing anything other than these parameters may result
// inference and evaluation problems, potentially resulting in a
// stack overflow. All open TRef types must be preserved !!!
//
// Derferences a type. This type must only be used in the context
// of dereferencing TComputed parameters. Attempting to deref
// outside parameters will result in stack overflow.
// ------------------------------------------------------------------
// prettier-ignore
type TDerefParameters<ModuleProperties extends TProperties, Types extends TSchema[], Result extends TSchema[] = []> = (
Expand Down Expand Up @@ -141,7 +142,18 @@ function FromPick<Parameters extends TSchema[]>(parameters: Parameters): TFromPi
return Pick(parameters[0], parameters[1]) as never
}
// ------------------------------------------------------------------
// ComputeComputed
// Required
// ------------------------------------------------------------------
// prettier-ignore
type TFromRequired<Parameters extends TSchema[]> = (
Parameters extends [infer T0 extends TSchema] ? TRequired<T0> : TNever
)
// prettier-ignore
function FromRequired<Parameters extends TSchema[]>(parameters: Parameters): TFromPick<Parameters> {
return Required(parameters[0]) as never
}
// ------------------------------------------------------------------
// Computed
// ------------------------------------------------------------------
// prettier-ignore
type TFromComputed<ModuleProperties extends TProperties, Target extends string, Parameters extends TSchema[],
Expand All @@ -151,6 +163,7 @@ type TFromComputed<ModuleProperties extends TProperties, Target extends string,
Target extends 'Partial' ? TFromPartial<Dereferenced> :
Target extends 'Omit' ? TFromOmit<Dereferenced> :
Target extends 'Pick' ? TFromPick<Dereferenced> :
Target extends 'Required' ? TFromRequired<Dereferenced> :
TNever
)
// prettier-ignore
Expand All @@ -161,6 +174,7 @@ function FromComputed<ModuleProperties extends TProperties, Target extends strin
target === 'Partial' ? FromPartial(dereferenced) :
target === 'Omit' ? FromOmit(dereferenced) :
target === 'Pick' ? FromPick(dereferenced) :
target === 'Required' ? FromRequired(dereferenced) :
Never()
) as never
}
Expand Down
4 changes: 2 additions & 2 deletions src/type/omit/omit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ function OmitResolve<Properties extends TSchema, PropertyKeys extends PropertyKe
// ------------------------------------------------------------------
// TOmit
//
// This mapping logic is to overly complex because of the decision
// This mapping logic is to overly complex because of the decision
// to use PropertyKey[] as the default selector. The PropertyKey[]
// did make TMapped types simpler to implement, but a non-TSchema
// selector makes supporting TComputed awkward as it requires
Expand Down Expand Up @@ -189,4 +189,4 @@ export function Omit(type: any, key: any, options?: SchemaOptions): any {
(isTypeRef && !isKeyRef) ? Computed('Omit', [type, typeKey], options) :
CreateType({ ...OmitResolve(type, propertyKeys), ...options })
) as never
}
}
49 changes: 24 additions & 25 deletions src/type/partial/partial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ type TFromProperties<Properties extends TProperties> = Evaluate<{
TOptional<Properties[K]>
}>
// prettier-ignore
function FromProperties<Properties extends TProperties>(T: Properties): TFromProperties<Properties> {
const properties = {} as TProperties
for(const K of globalThis.Object.getOwnPropertyNames(T)) properties[K] = Optional(T[K])
return properties as never
function FromProperties<Properties extends TProperties>(properties: Properties): TFromProperties<Properties> {
const partialProperties = {} as TProperties
for(const K of globalThis.Object.getOwnPropertyNames(properties)) partialProperties[K] = Optional(properties[K])
return partialProperties as never
}
// ------------------------------------------------------------------
// FromObject
Expand All @@ -100,7 +100,19 @@ function FromObject<Type extends TObject>(T: Type): TFromObject<Type> {
const properties = FromProperties(T['properties'])
return Object(properties, options) as never
}

// ------------------------------------------------------------------
// FromRest
// ------------------------------------------------------------------
// prettier-ignore
type TFromRest<Types extends TSchema[], Result extends TSchema[] = []> = (
Types extends [infer L extends TSchema, ...infer R extends TSchema[]]
? TFromRest<R, [...Result, TPartial<L>]>
: Result
)
// prettier-ignore
function FromRest<Types extends TSchema[]>(types: [...Types]): TFromRest<Types> {
return types.map(type => PartialResolve(type)) as never
}
// ------------------------------------------------------------------
// PartialResolve
// ------------------------------------------------------------------
Expand All @@ -116,41 +128,28 @@ function PartialResolve<Type extends TSchema>(type: Type): TPartial<Type> {
) as never
}
// ------------------------------------------------------------------
// FromRest
// ------------------------------------------------------------------
// prettier-ignore
type TFromRest<Types extends TSchema[], Result extends TSchema[] = []> = (
Types extends [infer L extends TSchema, ...infer R extends TSchema[]]
? TFromRest<R, [...Result, TPartial<L>]>
: Result
)
// prettier-ignore
function FromRest<Types extends TSchema[]>(types: [...Types]): TFromRest<Types> {
return types.map(L => PartialResolve(L)) as never
}
// ------------------------------------------------------------------
// TPartial
// ------------------------------------------------------------------
// prettier-ignore
export type TPartial<T extends TSchema> = (
T extends TRecursive<infer Type extends TSchema> ? TRecursive<TPartial<Type>> :
T extends TComputed<infer Target extends string, infer Parameters extends TSchema[]> ? TFromComputed<Target, Parameters> :
T extends TRef<infer Ref extends string> ? TFromRef<Ref> :
T extends TIntersect<infer Types extends TSchema[]> ? TIntersect<TFromRest<Types>> :
T extends TUnion<infer Types extends TSchema[]> ? TUnion<TFromRest<Types>> :
T extends TObject<infer Properties extends TProperties> ? TFromObject<TObject<Properties>> :
T extends TRef<infer Ref extends string> ? TFromRef<Ref> :
TObject<{}>
)
/** `[Json]` Constructs a type where all properties are optional */
export function Partial<T extends TMappedResult>(T: T, options?: SchemaOptions): TPartialFromMappedResult<T>
export function Partial<MappedResult extends TMappedResult>(type: MappedResult, options?: SchemaOptions): TPartialFromMappedResult<MappedResult>
/** `[Json]` Constructs a type where all properties are optional */
export function Partial<T extends TSchema>(T: T, options?: SchemaOptions): TPartial<T>
export function Partial<Type extends TSchema>(type: Type, options?: SchemaOptions): TPartial<Type>
/** `[Json]` Constructs a type where all properties are optional */
export function Partial(T: TSchema, options?: SchemaOptions): any {
if (IsMappedResult(T)) {
return PartialFromMappedResult(T, options)
export function Partial(type: TSchema, options?: SchemaOptions): any {
if (IsMappedResult(type)) {
return PartialFromMappedResult(type, options)
} else {
// special: mapping types require overridable options
return CreateType({ ...PartialResolve(T), ...options })
return CreateType({ ...PartialResolve(type), ...options })
}
}
2 changes: 1 addition & 1 deletion src/type/pick/pick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ function PickResolve<Properties extends TSchema, PropertyKeys extends PropertyKe
// ------------------------------------------------------------------
// TPick
//
// This mapping logic is to overly complex because of the decision
// This mapping logic is to overly complex because of the decision
// to use PropertyKey[] as the default selector. The PropertyKey[]
// did make TMapped types simpler to implement, but a non-TSchema
// selector makes supporting TComputed awkward as it requires
Expand Down
1 change: 0 additions & 1 deletion src/type/required/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,4 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/

export * from './required-from-mapped-result'
export * from './required-ref'
export * from './required'
41 changes: 0 additions & 41 deletions src/type/required/required-ref.ts

This file was deleted.

Loading

0 comments on commit c76f2cf

Please sign in to comment.