@sinclair/typebox 0.26.1 → 0.26.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sinclair/typebox",
3
- "version": "0.26.1",
3
+ "version": "0.26.2",
4
4
  "description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
package/readme.md CHANGED
@@ -229,13 +229,13 @@ The following table lists the Standard TypeBox types. These types are fully comp
229
229
  │ │ │ │
230
230
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
231
231
  │ const T = Type.Null() │ type T = null │ const T = { │
232
- │ │ │ type: 'null'
232
+ │ │ │ type: 'null'
233
233
  │ │ │ } │
234
234
  │ │ │ │
235
235
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
236
236
  │ const T = Type.Literal(42) │ type T = 42 │ const T = { │
237
- │ │ │ const: 42,
238
- │ │ │ type: 'number'
237
+ │ │ │ const: 42,
238
+ │ │ │ type: 'number'
239
239
  │ │ │ } │
240
240
  │ │ │ │
241
241
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
@@ -326,19 +326,16 @@ The following table lists the Standard TypeBox types. These types are fully comp
326
326
  │ │ │ │
327
327
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
328
328
  │ const T = Type.Composite([ │ type T = { │ const T = { │
329
- │ Type.Object({ │ x: number | string │ type: 'object', │
330
- │ x: Type.Number() │ y: number │ properties: {
331
- │ }), │ } │ x: {
332
- │ Type.Object({ │ │ anyOf: [
333
- x: Type.String() │ │ { type: 'number' },
334
- y: Type.Number() │ │ { type: 'string' }
335
- }) │ │ ]
336
- │ ]) │ │ }, │
337
- │ │ │ y: { │
329
+ │ Type.Object({ │ x: number │ type: 'object', │
330
+ │ x: Type.Number() │ y: number │ required: ['x', 'y'],
331
+ │ }), │ } │ properties: {
332
+ │ Type.Object({ │ │ x: {
333
+ y: Type.Number() │ │ type: 'number'
334
+ }) │ │ },
335
+ ]) │ │ y: {
338
336
  │ │ │ type: 'number' │
339
337
  │ │ │ } │
340
- │ │ │ },
341
- │ │ │ required: ['x', 'y'] │
338
+ │ │ │ }
342
339
  │ │ │ } │
343
340
  │ │ │ │
344
341
  ├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┤
package/typebox.d.ts CHANGED
@@ -83,16 +83,18 @@ export interface TBoolean extends TSchema {
83
83
  }
84
84
  export type TConstructorParameters<T extends TConstructor<TSchema[], TSchema>> = TTuple<T['parameters']>;
85
85
  export type TInstanceType<T extends TConstructor<TSchema[], TSchema>> = T['returns'];
86
- export type TCompositeUnion<Left extends TSchema, Right extends TSchema> = Ensure<TUnion<[Left, Right]>>;
87
- export type TCompositeUnionLeft<T extends TObject, Acc extends TProperties> = {
88
- [K in keyof T['properties']]: K extends keyof Acc ? TCompositeUnion<T['properties'][K], Acc[K]> : T['properties'][K];
86
+ export type TCompositeEvaluateArray<T extends readonly TSchema[], P extends unknown[]> = {
87
+ [K in keyof T]: T[K] extends TSchema ? Static<T[K], P> : never;
89
88
  };
90
- export type TCompositeUnionRight<T extends TObject, Acc extends TProperties> = {
91
- [K in keyof Acc]: K extends keyof T['properties'] ? TCompositeUnion<T['properties'][K], Acc[K]> : Acc[K];
89
+ export type TCompositeArray<T extends readonly TObject[]> = {
90
+ [K in keyof T]: T[K] extends TObject<infer P> ? P : {};
92
91
  };
93
- export type TCompositeUnionObject<T extends TObject, Acc extends TProperties> = Evaluate<TCompositeUnionLeft<T, Acc> & TCompositeUnionRight<T, Acc>>;
94
- export type TCompositeProperties<T extends TObject[], Acc extends TProperties> = T extends [...infer L, infer R] ? TCompositeProperties<Assert<L, TObject[]>, TCompositeUnionObject<Assert<R, TObject>, Acc>> : T extends [] ? Acc : never;
95
- export type TComposite<T extends TObject[] = TObject[]> = Ensure<TObject<TCompositeProperties<T, {}>>>;
92
+ export type TCompositeProperties<I extends unknown, T extends readonly any[]> = Evaluate<T extends [infer A, ...infer B] ? TCompositeProperties<I & A, B> : I extends object ? I : {}>;
93
+ export interface TComposite<T extends TObject[] = TObject[]> extends TObject {
94
+ [Hint]: 'Composite';
95
+ static: Evaluate<TCompositeProperties<unknown, TCompositeEvaluateArray<T, this['params']>>>;
96
+ properties: TCompositeProperties<unknown, TCompositeArray<T>>;
97
+ }
96
98
  export type TConstructorParameterArray<T extends readonly TSchema[], P extends unknown[]> = [...{
97
99
  [K in keyof T]: Static<Assert<T[K], TSchema>, P>;
98
100
  }];
@@ -169,7 +171,7 @@ export type TKeyOfTuple<T extends TSchema> = {
169
171
  } extends infer U ? UnionToTuple<Exclude<{
170
172
  [K in keyof U]: U[K];
171
173
  }[keyof U], undefined>> : never;
172
- export type TKeyOf<T extends TSchema = TSchema> = (T extends TIntersect ? TKeyOfTuple<T> : T extends TUnion ? TKeyOfTuple<T> : T extends TObject ? TKeyOfTuple<T> : [
174
+ export type TKeyOf<T extends TSchema = TSchema> = (T extends TComposite ? TKeyOfTuple<T> : T extends TIntersect ? TKeyOfTuple<T> : T extends TUnion ? TKeyOfTuple<T> : T extends TObject ? TKeyOfTuple<T> : [
173
175
  ]) extends infer R ? TUnionResult<Assert<R, TSchema[]>> : never;
174
176
  export type TLiteralValue = string | number | boolean;
175
177
  export interface TLiteral<T extends TLiteralValue = TLiteralValue> extends TSchema {
@@ -180,13 +182,7 @@ export interface TLiteral<T extends TLiteralValue = TLiteralValue> extends TSche
180
182
  export interface TNever extends TSchema {
181
183
  [Kind]: 'Never';
182
184
  static: never;
183
- allOf: [{
184
- type: 'boolean';
185
- const: false;
186
- }, {
187
- type: 'boolean';
188
- const: true;
189
- }];
185
+ not: {};
190
186
  }
191
187
  export type TNotStatic<_ extends TSchema = TSchema, T extends TSchema = TSchema> = Static<T>;
192
188
  export interface TNot<Not extends TSchema = TSchema, T extends TSchema = TSchema> extends TSchema {
@@ -241,22 +237,25 @@ export type TOmitArray<T extends TSchema[], K extends keyof any> = Assert<{
241
237
  [K2 in keyof T]: TOmit<Assert<T[K2], TSchema>, K>;
242
238
  }, TSchema[]>;
243
239
  export type TOmitProperties<T extends TProperties, K extends keyof any> = Evaluate<Assert<Omit<T, K>, TProperties>>;
244
- export type TOmit<T extends TSchema, K extends keyof any> = T extends TIntersect<infer S> ? TIntersect<TOmitArray<S, K>> : T extends TUnion<infer S> ? TUnion<TOmitArray<S, K>> : T extends TObject<infer S> ? TObject<TOmitProperties<S, K>> : T;
240
+ export type TOmit<T extends TSchema, K extends keyof any> = T extends TComposite<infer S> ? TComposite<TOmitArray<S, K>> : T extends TIntersect<infer S> ? TIntersect<TOmitArray<S, K>> : T extends TUnion<infer S> ? TUnion<TOmitArray<S, K>> : T extends TObject<infer S> ? TObject<TOmitProperties<S, K>> : T;
245
241
  export type TParameters<T extends TFunction> = TTuple<T['parameters']>;
242
+ export type TPartialObjectArray<T extends TObject[]> = Assert<{
243
+ [K in keyof T]: TPartial<Assert<T[K], TObject>>;
244
+ }, TObject[]>;
246
245
  export type TPartialArray<T extends TSchema[]> = Assert<{
247
246
  [K in keyof T]: TPartial<Assert<T[K], TSchema>>;
248
247
  }, TSchema[]>;
249
248
  export type TPartialProperties<T extends TProperties> = Evaluate<Assert<{
250
249
  [K in keyof T]: T[K] extends TReadonlyOptional<infer U> ? TReadonlyOptional<U> : T[K] extends TReadonly<infer U> ? TReadonlyOptional<U> : T[K] extends TOptional<infer U> ? TOptional<U> : TOptional<T[K]>;
251
250
  }, TProperties>>;
252
- export type TPartial<T extends TSchema> = T extends TIntersect<infer S> ? TIntersect<TPartialArray<S>> : T extends TUnion<infer S> ? TUnion<TPartialArray<S>> : T extends TObject<infer S> ? TObject<TPartialProperties<S>> : T;
251
+ export type TPartial<T extends TSchema> = T extends TComposite<infer S> ? TComposite<TPartialArray<S>> : T extends TIntersect<infer S> ? TIntersect<TPartialArray<S>> : T extends TUnion<infer S> ? TUnion<TPartialArray<S>> : T extends TObject<infer S> ? TObject<TPartialProperties<S>> : T;
253
252
  export type TPickArray<T extends TSchema[], K extends keyof any> = {
254
253
  [K2 in keyof T]: TPick<Assert<T[K2], TSchema>, K>;
255
254
  };
256
255
  export type TPickProperties<T extends TProperties, K extends keyof any> = Pick<T, Assert<Extract<K, keyof T>, keyof T>> extends infer R ? ({
257
256
  [K in keyof R]: Assert<R[K], TSchema> extends TSchema ? R[K] : never;
258
257
  }) : never;
259
- export type TPick<T extends TSchema, K extends keyof any> = T extends TIntersect<infer S> ? TIntersect<TPickArray<S, K>> : T extends TUnion<infer S> ? TUnion<TPickArray<S, K>> : T extends TObject<infer S> ? TObject<TPickProperties<S, K>> : T;
258
+ export type TPick<T extends TSchema, K extends keyof any> = T extends TComposite<infer S> ? TComposite<TPickArray<S, K>> : T extends TIntersect<infer S> ? TIntersect<TPickArray<S, K>> : T extends TUnion<infer S> ? TUnion<TPickArray<S, K>> : T extends TObject<infer S> ? TObject<TPickProperties<S, K>> : T;
260
259
  export type TPromiseStatic<T extends TSchema, P extends unknown[]> = Promise<Static<T, P>>;
261
260
  export interface TPromise<T extends TSchema = TSchema> extends TSchema {
262
261
  [Kind]: 'Promise';
@@ -304,7 +303,7 @@ export type TRequiredArray<T extends TSchema[]> = Assert<{
304
303
  export type TRequiredProperties<T extends TProperties> = Evaluate<Assert<{
305
304
  [K in keyof T]: T[K] extends TReadonlyOptional<infer U> ? TReadonly<U> : T[K] extends TReadonly<infer U> ? TReadonly<U> : T[K] extends TOptional<infer U> ? U : T[K];
306
305
  }, TProperties>>;
307
- export type TRequired<T extends TSchema> = T extends TIntersect<infer S> ? TIntersect<TRequiredArray<S>> : T extends TUnion<infer S> ? TUnion<TRequiredArray<S>> : T extends TObject<infer S> ? TObject<TRequiredProperties<S>> : T;
306
+ export type TRequired<T extends TSchema> = T extends TComposite<infer S> ? TComposite<TRequiredArray<S>> : T extends TIntersect<infer S> ? TIntersect<TRequiredArray<S>> : T extends TUnion<infer S> ? TUnion<TRequiredArray<S>> : T extends TObject<infer S> ? TObject<TRequiredProperties<S>> : T;
308
307
  export type StringFormatOption = 'date-time' | 'time' | 'date' | 'email' | 'idn-email' | 'hostname' | 'idn-hostname' | 'ipv4' | 'ipv6' | 'uri' | 'uri-reference' | 'iri' | 'uuid' | 'iri-reference' | 'uri-template' | 'json-pointer' | 'relative-json-pointer' | 'regex';
309
308
  export interface StringOptions<Format extends string> extends SchemaOptions {
310
309
  minLength?: number;
@@ -531,8 +530,8 @@ export declare class StandardTypeBuilder extends TypeBuilder {
531
530
  Array<T extends TSchema>(items: T, options?: ArrayOptions): TArray<T>;
532
531
  /** `[Standard]` Creates a Boolean type */
533
532
  Boolean(options?: SchemaOptions): TBoolean;
534
- /** `[Standard]` Creates a Composite object type that will union any overlapping properties of the given object array */
535
- Composite<T extends TObject[]>(schemas: [...T], options?: ObjectOptions): TComposite<T>;
533
+ /** `[Standard]` Creates a Composite object type. */
534
+ Composite<T extends TObject[]>(objects: [...T], options?: ObjectOptions): TComposite<T>;
536
535
  /** `[Standard]` Creates a Enum type */
537
536
  Enum<T extends Record<string, string | number>>(item: T, options?: SchemaOptions): TEnum<T>;
538
537
  /** `[Standard]` A conditional type expression that will return the true type if the left type extends the right */
package/typebox.js CHANGED
@@ -1465,15 +1465,48 @@ class StandardTypeBuilder extends TypeBuilder {
1465
1465
  Boolean(options = {}) {
1466
1466
  return this.Create({ ...options, [exports.Kind]: 'Boolean', type: 'boolean' });
1467
1467
  }
1468
- /** `[Standard]` Creates a Composite object type that will union any overlapping properties of the given object array */
1469
- Composite(schemas, options) {
1468
+ /** `[Standard]` Creates a Composite object type. */
1469
+ Composite(objects, options) {
1470
+ const isOptionalAll = (objects, key) => objects.every((object) => !(key in object.properties) || IsOptional(object.properties[key]));
1471
+ const IsOptional = (schema) => TypeGuard.TOptional(schema) || TypeGuard.TReadonlyOptional(schema);
1472
+ const [required, optional] = [new Set(), new Set()];
1473
+ for (const object of objects) {
1474
+ for (const key of globalThis.Object.getOwnPropertyNames(object.properties)) {
1475
+ if (isOptionalAll(objects, key))
1476
+ optional.add(key);
1477
+ }
1478
+ }
1479
+ for (const object of objects) {
1480
+ for (const key of globalThis.Object.getOwnPropertyNames(object.properties)) {
1481
+ if (!optional.has(key))
1482
+ required.add(key);
1483
+ }
1484
+ }
1470
1485
  const properties = {};
1471
- for (const object of schemas) {
1472
- for (const [key, property] of globalThis.Object.entries(object.properties)) {
1473
- properties[key] = key in properties ? this.Union([properties[key], property]) : TypeClone.Clone(property, {});
1486
+ for (const object of objects) {
1487
+ for (const [key, schema] of Object.entries(object.properties)) {
1488
+ const property = TypeClone.Clone(schema, {});
1489
+ if (!optional.has(key))
1490
+ delete property[exports.Modifier];
1491
+ if (key in properties) {
1492
+ const left = TypeExtends.Extends(properties[key], property) !== TypeExtendsResult.False;
1493
+ const right = TypeExtends.Extends(property, properties[key]) !== TypeExtendsResult.False;
1494
+ if (!left && !right)
1495
+ properties[key] = exports.Type.Never();
1496
+ if (!left && right)
1497
+ properties[key] = property;
1498
+ }
1499
+ else {
1500
+ properties[key] = property;
1501
+ }
1474
1502
  }
1475
1503
  }
1476
- return this.Object(properties, options);
1504
+ if (required.size > 0) {
1505
+ return this.Create({ ...options, [exports.Kind]: 'Object', [exports.Hint]: 'Composite', type: 'object', properties, required: [...required] });
1506
+ }
1507
+ else {
1508
+ return this.Create({ ...options, [exports.Kind]: 'Object', [exports.Hint]: 'Composite', type: 'object', properties });
1509
+ }
1477
1510
  }
1478
1511
  /** `[Standard]` Creates a Enum type */
1479
1512
  Enum(item, options = {}) {