@nmtjs/type 0.5.3 → 0.6.0

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.
Files changed (59) hide show
  1. package/dist/compiler.js +16 -79
  2. package/dist/compiler.js.map +1 -1
  3. package/dist/index.js +30 -54
  4. package/dist/index.js.map +1 -1
  5. package/dist/inference.js +1 -0
  6. package/dist/inference.js.map +1 -0
  7. package/dist/parse.js +145 -0
  8. package/dist/parse.js.map +1 -0
  9. package/dist/runtime.js +73 -0
  10. package/dist/runtime.js.map +1 -0
  11. package/dist/schemas/default.js +6 -0
  12. package/dist/schemas/default.js.map +1 -0
  13. package/dist/schemas/discriminated-union.js.map +1 -1
  14. package/dist/schemas/nullable.js.map +1 -1
  15. package/dist/temporal.js.map +1 -1
  16. package/dist/types/any.js.map +1 -1
  17. package/dist/types/array.js +1 -1
  18. package/dist/types/array.js.map +1 -1
  19. package/dist/types/base.js +4 -16
  20. package/dist/types/base.js.map +1 -1
  21. package/dist/types/boolean.js.map +1 -1
  22. package/dist/types/custom.js.map +1 -1
  23. package/dist/types/date.js +9 -1
  24. package/dist/types/date.js.map +1 -1
  25. package/dist/types/enum.js +6 -2
  26. package/dist/types/enum.js.map +1 -1
  27. package/dist/types/literal.js +3 -1
  28. package/dist/types/literal.js.map +1 -1
  29. package/dist/types/never.js.map +1 -1
  30. package/dist/types/number.js +2 -0
  31. package/dist/types/number.js.map +1 -1
  32. package/dist/types/object.js +32 -1
  33. package/dist/types/object.js.map +1 -1
  34. package/dist/types/string.js.map +1 -1
  35. package/dist/types/union.js +9 -5
  36. package/dist/types/union.js.map +1 -1
  37. package/package.json +8 -8
  38. package/src/compiler.ts +36 -121
  39. package/src/index.ts +36 -119
  40. package/src/inference.ts +128 -0
  41. package/src/parse.ts +217 -0
  42. package/src/runtime.ts +137 -0
  43. package/src/schemas/default.ts +12 -0
  44. package/src/schemas/discriminated-union.ts +1 -1
  45. package/src/schemas/nullable.ts +0 -6
  46. package/src/temporal.ts +0 -1
  47. package/src/types/any.ts +2 -4
  48. package/src/types/array.ts +1 -12
  49. package/src/types/base.ts +45 -144
  50. package/src/types/boolean.ts +3 -10
  51. package/src/types/custom.ts +14 -13
  52. package/src/types/date.ts +13 -1
  53. package/src/types/enum.ts +12 -15
  54. package/src/types/literal.ts +3 -5
  55. package/src/types/never.ts +2 -4
  56. package/src/types/number.ts +18 -18
  57. package/src/types/object.ts +108 -43
  58. package/src/types/string.ts +8 -5
  59. package/src/types/union.ts +43 -78
package/src/parse.ts ADDED
@@ -0,0 +1,217 @@
1
+ // --------------------------------------------------------------------------
2
+ // Iterators
3
+ // --------------------------------------------------------------------------
4
+
5
+ /** Returns true if this value is an async iterator */
6
+ export function IsAsyncIterator(value) {
7
+ return IsObject(value) && Symbol.asyncIterator in value
8
+ }
9
+ /** Returns true if this value is an iterator */
10
+ export function IsIterator(value) {
11
+ return IsObject(value) && Symbol.iterator in value
12
+ }
13
+ // --------------------------------------------------------------------------
14
+ // Object Instances
15
+ // --------------------------------------------------------------------------
16
+ /** Returns true if this value is not an instance of a class */
17
+ export function IsStandardObject(value) {
18
+ return (
19
+ IsObject(value) &&
20
+ (Object.getPrototypeOf(value) === Object.prototype ||
21
+ Object.getPrototypeOf(value) === null)
22
+ )
23
+ }
24
+ /** Returns true if this value is an instance of a class */
25
+ export function IsInstanceObject(value) {
26
+ return (
27
+ IsObject(value) &&
28
+ !IsArray(value) &&
29
+ IsFunction(value.constructor) &&
30
+ value.constructor.name !== 'Object'
31
+ )
32
+ }
33
+ // --------------------------------------------------------------------------
34
+ // JavaScript
35
+ // --------------------------------------------------------------------------
36
+ /** Returns true if this value is a Promise */
37
+ export function IsPromise(value) {
38
+ return value instanceof Promise
39
+ }
40
+ /** Returns true if this value is a Date */
41
+ export function IsDate(value) {
42
+ return value instanceof Date && Number.isFinite(value.getTime())
43
+ }
44
+ /** Returns true if this value is an instance of Map<K, T> */
45
+ export function IsMap(value) {
46
+ return value instanceof globalThis.Map
47
+ }
48
+ /** Returns true if this value is an instance of Set<T> */
49
+ export function IsSet(value) {
50
+ return value instanceof globalThis.Set
51
+ }
52
+ /** Returns true if this value is RegExp */
53
+ export function IsRegExp(value) {
54
+ return value instanceof globalThis.RegExp
55
+ }
56
+ /** Returns true if this value is a typed array */
57
+ export function IsTypedArray(value) {
58
+ return ArrayBuffer.isView(value)
59
+ }
60
+ /** Returns true if the value is a Int8Array */
61
+ export function IsInt8Array(value) {
62
+ return value instanceof globalThis.Int8Array
63
+ }
64
+ /** Returns true if the value is a Uint8Array */
65
+ export function IsUint8Array(value) {
66
+ return value instanceof globalThis.Uint8Array
67
+ }
68
+ /** Returns true if the value is a Uint8ClampedArray */
69
+ export function IsUint8ClampedArray(value) {
70
+ return value instanceof globalThis.Uint8ClampedArray
71
+ }
72
+ /** Returns true if the value is a Int16Array */
73
+ export function IsInt16Array(value) {
74
+ return value instanceof globalThis.Int16Array
75
+ }
76
+ /** Returns true if the value is a Uint16Array */
77
+ export function IsUint16Array(value) {
78
+ return value instanceof globalThis.Uint16Array
79
+ }
80
+ /** Returns true if the value is a Int32Array */
81
+ export function IsInt32Array(value) {
82
+ return value instanceof globalThis.Int32Array
83
+ }
84
+ /** Returns true if the value is a Uint32Array */
85
+ export function IsUint32Array(value) {
86
+ return value instanceof globalThis.Uint32Array
87
+ }
88
+ /** Returns true if the value is a Float32Array */
89
+ export function IsFloat32Array(value) {
90
+ return value instanceof globalThis.Float32Array
91
+ }
92
+ /** Returns true if the value is a Float64Array */
93
+ export function IsFloat64Array(value) {
94
+ return value instanceof globalThis.Float64Array
95
+ }
96
+ /** Returns true if the value is a BigInt64Array */
97
+ export function IsBigInt64Array(value) {
98
+ return value instanceof globalThis.BigInt64Array
99
+ }
100
+ /** Returns true if the value is a BigUint64Array */
101
+ export function IsBigUint64Array(value) {
102
+ return value instanceof globalThis.BigUint64Array
103
+ }
104
+ // --------------------------------------------------------------------------
105
+ // PropertyKey
106
+ // --------------------------------------------------------------------------
107
+ /** Returns true if this value has this property key */
108
+ export function HasPropertyKey(value, key) {
109
+ return key in value
110
+ }
111
+ // --------------------------------------------------------------------------
112
+ // Standard
113
+ // --------------------------------------------------------------------------
114
+ /** Returns true of this value is an object type */
115
+ export function IsObject(value) {
116
+ return value !== null && typeof value === 'object'
117
+ }
118
+ /** Returns true if this value is an array, but not a typed array */
119
+ export function IsArray(value) {
120
+ return Array.isArray(value) && !ArrayBuffer.isView(value)
121
+ }
122
+ /** Returns true if this value is an undefined */
123
+ export function IsUndefined(value) {
124
+ return value === undefined
125
+ }
126
+ /** Returns true if this value is an null */
127
+ export function IsNull(value) {
128
+ return value === null
129
+ }
130
+ /** Returns true if this value is an boolean */
131
+ export function IsBoolean(value) {
132
+ return typeof value === 'boolean'
133
+ }
134
+ /** Returns true if this value is an number */
135
+ export function IsNumber(value) {
136
+ return typeof value === 'number'
137
+ }
138
+ /** Returns true if this value is an integer */
139
+ export function IsInteger(value) {
140
+ return Number.isInteger(value)
141
+ }
142
+ /** Returns true if this value is bigint */
143
+ export function IsBigInt(value) {
144
+ return typeof value === 'bigint'
145
+ }
146
+ /** Returns true if this value is string */
147
+ export function IsString(value) {
148
+ return typeof value === 'string'
149
+ }
150
+ /** Returns true if this value is a function */
151
+ export function IsFunction(value) {
152
+ return typeof value === 'function'
153
+ }
154
+ /** Returns true if this value is a symbol */
155
+ export function IsSymbol(value) {
156
+ return typeof value === 'symbol'
157
+ }
158
+ /** Returns true if this value is a value type such as number, string, boolean */
159
+ export function IsValueType(value) {
160
+ // prettier-ignore
161
+ return (
162
+ IsBigInt(value) ||
163
+ IsBoolean(value) ||
164
+ IsNull(value) ||
165
+ IsNumber(value) ||
166
+ IsString(value) ||
167
+ IsSymbol(value) ||
168
+ IsUndefined(value)
169
+ )
170
+ }
171
+
172
+ // ------------------------------------------------------------------
173
+ // Clonable
174
+ // ------------------------------------------------------------------
175
+ function FromObject(value, exclude) {
176
+ const Acc = {}
177
+ for (const key of Object.getOwnPropertyNames(value)) {
178
+ Acc[key] = Clone(value[key], exclude)
179
+ }
180
+ for (const key of Object.getOwnPropertySymbols(value)) {
181
+ Acc[key] = Clone(value[key], exclude)
182
+ }
183
+ return Acc
184
+ }
185
+ function FromArray(value, exclude) {
186
+ return value.map((element) => Clone(element, exclude))
187
+ }
188
+ function FromTypedArray(value) {
189
+ return value.slice()
190
+ }
191
+ function FromMap(value, exclude) {
192
+ return new Map(Clone([...value.entries()], exclude))
193
+ }
194
+ function FromSet(value, exclude) {
195
+ return new Set(Clone([...value.entries()], exclude))
196
+ }
197
+ function FromDate(value) {
198
+ return new Date(value.toISOString())
199
+ }
200
+ function FromValue(value) {
201
+ return value
202
+ }
203
+ // ------------------------------------------------------------------
204
+ // Clone
205
+ // ------------------------------------------------------------------
206
+ /** Returns a clone of the given value */
207
+ export function Clone(value, exclude?: Set<any>) {
208
+ if (IsArray(value)) return FromArray(value, exclude)
209
+ if (IsDate(value)) return FromDate(value)
210
+ if (IsTypedArray(value)) return FromTypedArray(value)
211
+ if (IsMap(value)) return FromMap(value, exclude)
212
+ if (IsSet(value)) return FromSet(value, exclude)
213
+ if (IsObject(value)) return FromObject(value, exclude)
214
+ if (IsValueType(value)) return FromValue(value)
215
+ if (exclude?.has(value.constructor)) return value
216
+ throw new Error('Cannot clone value')
217
+ }
package/src/runtime.ts ADDED
@@ -0,0 +1,137 @@
1
+ import type { ClassConstructor } from '@nmtjs/common'
2
+ import type { TSchema } from '@sinclair/typebox'
3
+ import type { ValueErrorIterator } from '@sinclair/typebox/compiler'
4
+ import {
5
+ TransformDecode,
6
+ TransformEncode,
7
+ Value,
8
+ } from '@sinclair/typebox/value'
9
+ import { register } from './formats.ts'
10
+ import type {
11
+ StaticInputEncode,
12
+ StaticOutputDecode,
13
+ StaticOutputEncode,
14
+ } from './inference.ts'
15
+ import { Clone } from './parse.ts'
16
+ import { IsDiscriminatedUnion } from './schemas/discriminated-union.ts'
17
+ import type { BaseType } from './types/base.ts'
18
+
19
+ // register ajv formats
20
+ register()
21
+
22
+ export type CloneOptions = {
23
+ clone?: boolean
24
+ exclude?: Set<any>
25
+ }
26
+
27
+ export type ValidationError = {
28
+ path: string
29
+ message: string
30
+ value: unknown
31
+ }
32
+
33
+ // TODO: this one is very slow
34
+ export function _applyDefaults(schema: TSchema, value: any) {
35
+ return Value.Default(schema, value)
36
+ }
37
+
38
+ // TODO: this one is very slow
39
+ // Clone -> Clean -> Convert
40
+ export function _parse(
41
+ schema: TSchema,
42
+ value: any,
43
+ cloneOptions?: CloneOptions,
44
+ ) {
45
+ if (cloneOptions?.clone !== false) {
46
+ value = Clone(value, cloneOptions?.exclude)
47
+ }
48
+ return Value.Clean(schema, Value.Convert(schema, value))
49
+ }
50
+
51
+ export function _traversErrors(errors: ValueErrorIterator) {
52
+ const result: ValidationError[] = []
53
+
54
+ for (const error of errors) {
55
+ if (IsDiscriminatedUnion(error.schema)) {
56
+ const discriminator = error.schema.discriminator
57
+ const discriminatorValue = error.value?.[discriminator]
58
+ if (discriminatorValue !== undefined) {
59
+ const variantSchema = error.schema.anyOf.find(
60
+ (schema) =>
61
+ schema.properties[discriminator].const === discriminatorValue,
62
+ )
63
+ if (variantSchema) {
64
+ const propertiesSchemas: TSchema[] = []
65
+ for (const element in variantSchema.properties) {
66
+ const propertySchema = variantSchema.properties[element]
67
+ if (propertySchema !== variantSchema.properties[discriminator]) {
68
+ propertiesSchemas.push(propertySchema)
69
+ }
70
+ }
71
+
72
+ for (const iter of error.errors) {
73
+ for (const err of iter) {
74
+ if (!propertiesSchemas.includes(err.schema)) continue
75
+ result.push({
76
+ path: err.path,
77
+ message: err.message,
78
+ value: err.value,
79
+ })
80
+ }
81
+ }
82
+
83
+ continue
84
+ }
85
+ }
86
+ }
87
+
88
+ result.push({
89
+ path: error.path,
90
+ message: error.message,
91
+ value: error.value,
92
+ })
93
+
94
+ for (const nestedError of error.errors) {
95
+ result.push(..._traversErrors(nestedError))
96
+ }
97
+ }
98
+
99
+ return result
100
+ }
101
+
102
+ export function applyDefaults(type: BaseType, value: unknown) {
103
+ return _applyDefaults(type.schema, value)
104
+ }
105
+
106
+ export function parse(
107
+ type: BaseType,
108
+ value: unknown,
109
+ cloneOptions?: CloneOptions,
110
+ ) {
111
+ return _parse(type.schema, value, cloneOptions)
112
+ }
113
+
114
+ export function errors(type: BaseType, value: unknown): ValidationError[] {
115
+ return _traversErrors(Value.Errors(type.schema, value))
116
+ }
117
+
118
+ export function check<T extends BaseType>(
119
+ type: T,
120
+ value: unknown,
121
+ ): value is StaticInputEncode<T['schema']> {
122
+ return Value.Check(type.schema, value)
123
+ }
124
+
125
+ export function decode<T extends BaseType>(
126
+ type: T,
127
+ value: unknown,
128
+ ): StaticOutputDecode<T['schema']> {
129
+ return TransformDecode(type.schema, [], value)
130
+ }
131
+
132
+ export function encode<T extends BaseType>(
133
+ type: T,
134
+ value: unknown,
135
+ ): StaticOutputEncode<T['schema']> {
136
+ return TransformEncode(type.schema, [], value)
137
+ }
@@ -0,0 +1,12 @@
1
+ import type { TSchema } from '@sinclair/typebox'
2
+
3
+ export type TDefault<Type extends TSchema, Default = unknown> = Type & {
4
+ default: Default
5
+ }
6
+
7
+ export function Default<Type extends TSchema, const Default>(
8
+ type: Type,
9
+ default_: Default,
10
+ ): TDefault<Type, Default> {
11
+ return { ...type, default: default_ } as never
12
+ }
@@ -25,7 +25,7 @@ export function IsDiscriminatedUnion(
25
25
  )
26
26
  }
27
27
 
28
- type DiscriminatedUnionProperties<K extends string = string> = {
28
+ export type DiscriminatedUnionProperties<K extends string = string> = {
29
29
  [OK in K]: TLiteral<any>
30
30
  } & {
31
31
  [OK in TPropertyKey]: any
@@ -1,9 +1,7 @@
1
1
  import {
2
2
  type SchemaOptions,
3
3
  type TNull,
4
- type TOptional,
5
4
  type TSchema,
6
- type TUndefined,
7
5
  type TUnion,
8
6
  Type,
9
7
  } from '@sinclair/typebox/type'
@@ -20,7 +18,3 @@ export const Nullable = <T extends TSchema>(
20
18
  ...options,
21
19
  })
22
20
  }
23
-
24
- export type TOptionalUndefined<T extends TSchema> = TOptional<
25
- TUnion<[T, TUndefined]>
26
- >
package/src/temporal.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { Temporal } from 'temporal-polyfill'
2
1
  import {
3
2
  DurationType,
4
3
  PlainDateTimeType,
package/src/types/any.ts CHANGED
@@ -1,9 +1,7 @@
1
1
  import { type TAny, Type } from '@sinclair/typebox'
2
- import { BaseType, type ConstantType } from './base.ts'
3
-
4
- export class AnyType extends BaseType<TAny> {
5
- declare _: ConstantType<this['schema']>
2
+ import { BaseType } from './base.ts'
6
3
 
4
+ export class AnyType extends BaseType<TAny, {}, any> {
7
5
  static factory() {
8
6
  return new AnyType(Type.Any())
9
7
  }
@@ -10,19 +10,8 @@ export class ArrayType<T extends BaseType = BaseType> extends BaseType<
10
10
  TArray<T['schema']>,
11
11
  { element: T; options: ArrayOptions }
12
12
  > {
13
- declare _: {
14
- encoded: {
15
- input: TArray<T['_']['encoded']['input']>
16
- output: TArray<T['_']['encoded']['output']>
17
- }
18
- decoded: {
19
- input: TArray<T['_']['decoded']['input']>
20
- output: TArray<T['_']['decoded']['output']>
21
- }
22
- }
23
-
24
13
  static factory<T extends BaseType>(element: T, options: ArrayOptions = {}) {
25
- return new ArrayType<T>(Type.Array(element.final, options))
14
+ return new ArrayType<T>(Type.Array(element.schema, options))
26
15
  }
27
16
 
28
17
  min(value: number) {
package/src/types/base.ts CHANGED
@@ -1,16 +1,6 @@
1
- import {
2
- Optional,
3
- type SchemaOptions,
4
- type StaticDecode,
5
- type StaticEncode,
6
- type TSchema,
7
- } from '@sinclair/typebox'
8
- import {
9
- Nullable,
10
- type TNullable,
11
- type TOptionalUndefined,
12
- } from '../schemas/nullable.ts'
13
- import type { Merge } from '../utils.ts'
1
+ import { Optional, type TOptional, type TSchema } from '@sinclair/typebox'
2
+ import { Default, type TDefault } from '../schemas/default.ts'
3
+ import { Nullable, type TNullable } from '../schemas/nullable.ts'
14
4
 
15
5
  export type TypeProps = Record<string, any>
16
6
 
@@ -28,85 +18,42 @@ export type DefaultTypeParams = {
28
18
  encode?: TypeParams['encode']
29
19
  }
30
20
 
31
- export type BaseTypeAny<T extends TSchema = TSchema> = BaseType<T, any, any>
32
-
33
- type ResolveNullable<
34
- T extends TSchema,
35
- P extends TypeParams,
36
- > = P['nullable'] extends true
37
- ? T extends TNullable<infer S>
38
- ? TNullable<S>
39
- : TNullable<T>
40
- : T
41
-
42
- type ResolveOptional<
43
- T extends TSchema,
44
- P extends TypeParams,
45
- > = P['optional'] extends true
46
- ? T extends TOptionalUndefined<infer S>
47
- ? TOptionalUndefined<S>
48
- : TOptionalUndefined<T>
49
- : T
50
-
51
- type ResolveDefault<
52
- T extends TSchema,
53
- P extends TypeParams,
54
- > = P['hasDefault'] extends true
55
- ? T extends TOptionalUndefined<infer U>
56
- ? U
57
- : T
58
- : T
21
+ export type BaseTypeAny<T extends TSchema = TSchema> = BaseType<
22
+ T,
23
+ TypeProps,
24
+ any
25
+ >
59
26
 
60
27
  export abstract class BaseType<
61
28
  Schema extends TSchema = TSchema,
62
29
  Props extends TypeProps = TypeProps,
63
- Params extends TypeParams = DefaultTypeParams,
30
+ ValueType = unknown,
64
31
  > {
65
- abstract _: {
66
- encoded: {
67
- input: TSchema
68
- output: TSchema
69
- }
70
- decoded: {
71
- input: TSchema
72
- output: TSchema
73
- }
74
- }
75
-
76
32
  readonly schema: Schema
77
- readonly final: TSchema
78
33
  readonly props: Props
79
- readonly params: Params
34
+ readonly params: TypeParams
80
35
 
81
36
  constructor(
82
37
  schema: Schema,
83
38
  props: Props = {} as Props,
84
- params: Params = {} as Params,
39
+ params: TypeParams = {} as TypeParams,
85
40
  ) {
86
41
  const { hasDefault = false, nullable = false, optional = false } = params
87
42
  this.schema = schema
88
- this.final = schema
89
-
90
- if (nullable)
91
- this.final = Nullable({
92
- ...this.final,
93
- default: this.final.default ?? null,
94
- }) as any
95
- if (optional || hasDefault) this.final = Optional(this.final) as any
96
43
 
97
44
  this.props = props
98
45
  this.params = {
99
46
  hasDefault,
100
47
  nullable,
101
48
  optional,
102
- } as Params
49
+ } as TypeParams
103
50
  }
104
51
 
105
- optional(): OptionalType<this> {
52
+ optional(): OptionalType<BaseType<Schema, Props>, ValueType> {
106
53
  return OptionalType.factory(this) as any
107
54
  }
108
55
 
109
- nullable(): NullableType<this> {
56
+ nullable(): NullableType<BaseType<Schema, Props>, ValueType> {
110
57
  return NullableType.factory(this) as any
111
58
  }
112
59
 
@@ -114,16 +61,14 @@ export abstract class BaseType<
114
61
  return this.nullable().optional()
115
62
  }
116
63
 
117
- default(
118
- value: StaticDecode<this['_']['decoded']['output']>,
119
- ): DefaultType<this> {
64
+ default(value: ValueType): DefaultType<BaseType<Schema, Props>, ValueType> {
120
65
  return DefaultType.factory(
121
66
  this,
122
67
  this.params.encode?.(value) ?? value,
123
68
  ) as any
124
69
  }
125
70
 
126
- description(description: string): this {
71
+ description(description: string): BaseType<Schema, Props, ValueType> {
127
72
  const ThisConstructor = this.constructor as any
128
73
  return new ThisConstructor(
129
74
  {
@@ -135,7 +80,7 @@ export abstract class BaseType<
135
80
  ) as any
136
81
  }
137
82
 
138
- examples(...examples: any[]): this {
83
+ examples(...examples: ValueType[]): BaseType<Schema, Props, ValueType> {
139
84
  const ThisConstructor = this.constructor as any
140
85
  return new ThisConstructor(
141
86
  {
@@ -148,89 +93,45 @@ export abstract class BaseType<
148
93
  }
149
94
  }
150
95
 
151
- export type ConstantType<T extends TSchema> = {
152
- encoded: {
153
- input: T
154
- output: T
155
- }
156
- decoded: {
157
- input: T
158
- output: T
159
- }
160
- }
161
-
162
- export type Static<
163
- T extends BaseTypeAny,
164
- P extends TypeProps,
165
- Params extends Merge<T['params'], P> = Merge<T['params'], P>,
166
- > = {
167
- encoded: {
168
- input: ResolveOptional<
169
- ResolveNullable<T['_']['encoded']['input'], Params>,
170
- Params
171
- >
172
- output: ResolveDefault<
173
- ResolveOptional<
174
- ResolveNullable<T['_']['encoded']['output'], Params>,
175
- Params
176
- >,
177
- Params
178
- >
179
- }
180
- decoded: {
181
- input: ResolveOptional<
182
- ResolveNullable<T['_']['decoded']['input'], Params>,
183
- Params
184
- >
185
- output: ResolveDefault<
186
- ResolveOptional<
187
- ResolveNullable<T['_']['decoded']['output'], Params>,
188
- Params
189
- >,
190
- Params
191
- >
192
- }
193
- }
194
-
195
96
  export class OptionalType<
196
- Type extends BaseTypeAny<any>,
197
- Params extends TypeParams = DefaultTypeParams,
198
- > extends BaseType<Type['schema'], { inner: Type }, Params> {
199
- _!: Static<Type, Params>
200
-
201
- static factory<T extends BaseTypeAny<any>>(type: T) {
202
- return new OptionalType<T, Merge<T['params'], { optional: true }>>(
203
- type.schema,
204
- { inner: type },
205
- { ...type.params, optional: true } as any,
206
- )
97
+ Type extends BaseTypeAny = BaseTypeAny,
98
+ ValueType = unknown,
99
+ > extends BaseType<TOptional<Type['schema']>, { inner: Type }, ValueType> {
100
+ static factory<T extends BaseTypeAny>(type: T) {
101
+ return new OptionalType<T>(Optional(type.schema) as any, { inner: type }, {
102
+ ...type.params,
103
+ optional: true,
104
+ } as any)
207
105
  }
208
106
  }
209
107
 
210
108
  export class NullableType<
211
- Type extends BaseTypeAny<any>,
212
- Params extends TypeParams = DefaultTypeParams,
213
- > extends BaseType<Type['schema'], { inner: Type }, Params> {
214
- _!: Static<Type, Params>
215
-
109
+ Type extends BaseTypeAny<any> = BaseTypeAny<any>,
110
+ ValueType = unknown,
111
+ > extends BaseType<
112
+ TNullable<Type['schema']>,
113
+ { inner: Type },
114
+ ValueType | null
115
+ > {
216
116
  static factory<T extends BaseTypeAny<any>>(type: T) {
217
- return new NullableType<T, Merge<T['params'], { nullable: true }>>(
218
- type.schema,
219
- { inner: type },
220
- { ...type.params, nullable: true } as any,
221
- )
117
+ return new NullableType<T>(Nullable(type.schema), { inner: type }, {
118
+ ...type.params,
119
+ nullable: true,
120
+ } as any)
222
121
  }
223
122
  }
224
123
 
225
124
  export class DefaultType<
226
- Type extends BaseTypeAny<any>,
227
- Params extends TypeParams = DefaultTypeParams,
228
- > extends BaseType<Type['schema'], { inner: Type }, Params> {
229
- _!: Static<Type, Params>
230
-
125
+ Type extends BaseTypeAny = BaseTypeAny,
126
+ ValueType = unknown,
127
+ > extends BaseType<
128
+ TDefault<TOptional<Type['schema']>>,
129
+ { inner: Type },
130
+ ValueType
131
+ > {
231
132
  static factory<T extends BaseTypeAny<any>>(type: T, defaultValue: any) {
232
- return new DefaultType<T, Merge<T['params'], { hasDefault: true }>>(
233
- { ...type.schema, default: defaultValue },
133
+ return new DefaultType<T>(
134
+ Default(Optional(type.schema), defaultValue) as any,
234
135
  { inner: type },
235
136
  { ...type.params, hasDefault: true } as any,
236
137
  )