@scalar/validation 0.2.0 → 0.3.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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +6 -0
- package/dist/schema.d.ts +7 -3
- package/dist/schema.d.ts.map +1 -1
- package/dist/types.d.ts +8 -4
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/coerce.test.ts +20 -0
- package/src/schema.ts +7 -3
- package/src/types.ts +12 -8
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
package/dist/schema.d.ts
CHANGED
|
@@ -62,7 +62,11 @@ export type OptionalSchema<S extends Schema> = {
|
|
|
62
62
|
type: 'optional';
|
|
63
63
|
schema: S;
|
|
64
64
|
} & Documentation;
|
|
65
|
-
|
|
65
|
+
/**
|
|
66
|
+
* `UnionSchema<any>` avoids a variance pitfall: `UnionSchema<[A, B]>` is not assignable to
|
|
67
|
+
* `UnionSchema<ObjectSchema<any>[]>`, which breaks `infer` when resolving `Static`.
|
|
68
|
+
*/
|
|
69
|
+
export type IntersectionSchema<Schemas extends readonly (ObjectSchema<any> | UnionSchema<any>)[]> = {
|
|
66
70
|
type: 'intersection';
|
|
67
71
|
schemas: Schemas;
|
|
68
72
|
} & Documentation;
|
|
@@ -89,7 +93,7 @@ export type EvaluateSchema<S extends Schema> = {
|
|
|
89
93
|
expression: (value: unknown) => unknown;
|
|
90
94
|
schema: S;
|
|
91
95
|
};
|
|
92
|
-
export type Schema = NumberSchema | StringSchema | BooleanSchema | NullableSchema | NotDefinedSchema | AnySchema | ArraySchema<any> | RecordSchema<any, any> | ObjectSchema<Record<string, any>> | UnionSchema<any[]> | OptionalSchema<any> | IntersectionSchema<readonly ObjectSchema<any>[]> | LiteralSchema<any> | LazySchema<any> | EvaluateSchema<any>;
|
|
96
|
+
export type Schema = NumberSchema | StringSchema | BooleanSchema | NullableSchema | NotDefinedSchema | AnySchema | ArraySchema<any> | RecordSchema<any, any> | ObjectSchema<Record<string, any>> | UnionSchema<any[]> | OptionalSchema<any> | IntersectionSchema<readonly (ObjectSchema<any> | UnionSchema<ObjectSchema<any>[]>)[]> | LiteralSchema<any> | LazySchema<any> | EvaluateSchema<any>;
|
|
93
97
|
declare const number: (options?: Documentation) => NumberSchema;
|
|
94
98
|
declare const string: (options?: Documentation) => StringSchema;
|
|
95
99
|
declare const boolean: (options?: Documentation) => BooleanSchema;
|
|
@@ -100,7 +104,7 @@ declare const array: <Item extends Schema>(items: Item, options?: Documentation)
|
|
|
100
104
|
declare const record: <Key extends StringSchema | AnySchema, Value extends Schema>(key: Key, value: Value, options?: Documentation) => RecordSchema<Key, Value>;
|
|
101
105
|
declare const object: <Properties extends Record<string, Schema>>(properties: Properties, options?: Documentation) => ObjectSchema<Properties>;
|
|
102
106
|
declare const union: <Schemas extends Schema[]>(schemas: Schemas, options?: Documentation) => UnionSchema<Schemas>;
|
|
103
|
-
declare const intersection: <Schemas extends readonly ObjectSchema<any>[]>(schemas: Schemas, options?: Documentation) => IntersectionSchema<Schemas>;
|
|
107
|
+
declare const intersection: <const Schemas extends readonly (ObjectSchema<any> | UnionSchema<ObjectSchema<any>[]>)[]>(schemas: Schemas, options?: Documentation) => IntersectionSchema<Schemas>;
|
|
104
108
|
declare const optional: <S extends Schema>(schema: S, options?: Documentation) => OptionalSchema<S>;
|
|
105
109
|
declare const literal: <Value extends string | number | boolean | bigint>(value: Value) => LiteralSchema<Value>;
|
|
106
110
|
declare const lazy: <S extends () => Schema>(schema: S) => LazySchema<S>;
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,KAAK,aAAa,GAAG,OAAO,CAAC;IAC3B,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAA;IACnB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAC,CAAA;AAEF,6EAA6E;AAC7E,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,QAAQ,CAAA;CACf,GAAG,aAAa,CAAA;AAEjB,qEAAqE;AACrE,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,QAAQ,CAAA;CACf,GAAG,aAAa,CAAA;AAEjB,uEAAuE;AACvE,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,SAAS,CAAA;CAChB,GAAG,aAAa,CAAA;AAEjB,4DAA4D;AAC5D,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,UAAU,CAAA;CACjB,GAAG,aAAa,CAAA;AAEjB,qFAAqF;AACrF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,YAAY,CAAA;CACnB,GAAG,aAAa,CAAA;AAEjB,yFAAyF;AACzF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,KAAK,CAAA;CACZ,GAAG,aAAa,CAAA;AAEjB,iGAAiG;AACjG,MAAM,MAAM,WAAW,CAAC,IAAI,SAAS,MAAM,IAAI;IAC7C,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,IAAI,CAAA;CACZ,GAAG,aAAa,CAAA;AAEjB,4GAA4G;AAC5G,MAAM,MAAM,YAAY,CAAC,GAAG,SAAS,YAAY,GAAG,YAAY,GAAG,SAAS,EAAE,KAAK,SAAS,MAAM,IAAI;IACpG,IAAI,EAAE,QAAQ,CAAA;IACd,GAAG,EAAE,GAAG,CAAA;IACR,KAAK,EAAE,KAAK,CAAA;CACb,GAAG,aAAa,CAAA;AAEjB,yFAAyF;AACzF,MAAM,MAAM,YAAY,CAAC,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI;IACpE,IAAI,EAAE,QAAQ,CAAA;IACd,UAAU,EAAE,UAAU,CAAA;CACvB,GAAG,aAAa,CAAA;AAEjB,kHAAkH;AAClH,MAAM,MAAM,WAAW,CAAC,OAAO,SAAS,MAAM,EAAE,IAAI;IAClD,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;CACjB,GAAG,aAAa,CAAA;AAEjB;;;GAGG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,MAAM,IAAI;IAC7C,IAAI,EAAE,UAAU,CAAA;IAChB,MAAM,EAAE,CAAC,CAAA;CACV,GAAG,aAAa,CAAA;AAEjB,MAAM,MAAM,kBAAkB,CAAC,OAAO,SAAS,SAAS,YAAY,CAAC,GAAG,CAAC,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import type { AnySchema, ArraySchema, BooleanSchema, EvaluateSchema, IntersectionSchema, LazySchema, LiteralSchema, NotDefinedSchema, NullableSchema, NumberSchema, ObjectSchema, OptionalSchema, RecordSchema, StringSchema, UnionSchema } from './schema.js';
|
|
1
|
+
import type { AnySchema, ArraySchema, BooleanSchema, EvaluateSchema, IntersectionSchema, LazySchema, LiteralSchema, NotDefinedSchema, NullableSchema, NumberSchema, ObjectSchema, OptionalSchema, RecordSchema, Schema, StringSchema, UnionSchema } from './schema.js';
|
|
2
2
|
export type Static<T> = _Static<T, 10>;
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Folds intersection member schemas into an intersection of their static types.
|
|
5
|
+
* Uses `Schema` for tuple positions (not a narrower alias) so `infer First extends …` does not
|
|
6
|
+
* reject valid tuple elements and collapse to `{}`.
|
|
7
|
+
*/
|
|
8
|
+
type IntersectObjectStatics<Schemas extends readonly Schema[], Depth extends number> = Schemas extends readonly [] ? {} : Schemas extends readonly [infer First extends Schema, ...infer Rest extends readonly Schema[]] ? _Static<First, Depth> & IntersectObjectStatics<Rest, Depth> : {};
|
|
5
9
|
type OptionalPropertyKeys<P> = {
|
|
6
10
|
[K in keyof P]: P[K] extends OptionalSchema<any> ? K : never;
|
|
7
11
|
}[keyof P];
|
|
@@ -18,7 +22,7 @@ type ObjectStatics<Properties, Depth extends number> = [keyof Properties] extend
|
|
|
18
22
|
} & {
|
|
19
23
|
[K in OptionalPropertyKeys<Properties>]?: _Static<OptionalSchemaInner<Properties[K]>, Prev<Depth>>;
|
|
20
24
|
};
|
|
21
|
-
type _Static<T, Depth extends number = 10> = Depth extends 0 ? any : T extends LiteralSchema<infer Value> ? Value : T extends NumberSchema ? number : T extends StringSchema ? string : T extends BooleanSchema ? boolean : T extends NullableSchema ? null : T extends NotDefinedSchema ? undefined : T extends AnySchema ? any : T extends ArraySchema<infer Item> ? Array<_Static<Item, Prev<Depth>>> : T extends RecordSchema<infer Key, infer Value> ? Record<_Static<Key, Prev<Depth>> & PropertyKey, _Static<Value, Prev<Depth>>> : T extends ObjectSchema<infer Properties> ? ObjectStatics<Properties, Depth> : T extends OptionalSchema<infer S> ? _Static<S, Prev<Depth>> | undefined : T extends IntersectionSchema<infer Schemas
|
|
25
|
+
type _Static<T, Depth extends number = 10> = Depth extends 0 ? any : T extends LiteralSchema<infer Value> ? Value : T extends NumberSchema ? number : T extends StringSchema ? string : T extends BooleanSchema ? boolean : T extends NullableSchema ? null : T extends NotDefinedSchema ? undefined : T extends AnySchema ? any : T extends ArraySchema<infer Item> ? Array<_Static<Item, Prev<Depth>>> : T extends RecordSchema<infer Key, infer Value> ? Record<_Static<Key, Prev<Depth>> & PropertyKey, _Static<Value, Prev<Depth>>> : T extends ObjectSchema<infer Properties> ? ObjectStatics<Properties, Depth> : T extends OptionalSchema<infer S> ? _Static<S, Prev<Depth>> | undefined : T extends IntersectionSchema<infer Schemas> ? IntersectObjectStatics<Schemas, Prev<Depth>> : T extends UnionSchema<infer Schemas> ? _Static<Schemas[number], Prev<Depth>> : T extends EvaluateSchema<infer S> ? _Static<S, Prev<Depth>> : T extends LazySchema<infer S> ? _Static<ReturnType<S>, Prev<Depth>> : never;
|
|
22
26
|
type Prev<T extends number> = T extends 10 ? 9 : T extends 9 ? 8 : T extends 8 ? 7 : T extends 7 ? 6 : T extends 6 ? 5 : T extends 5 ? 4 : T extends 4 ? 3 : T extends 3 ? 2 : T extends 2 ? 1 : T extends 1 ? 0 : 0;
|
|
23
27
|
export {};
|
|
24
28
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,WAAW,EACZ,MAAM,UAAU,CAAA;AAGjB,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAEtC
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,WAAW,EACZ,MAAM,UAAU,CAAA;AAGjB,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAEtC;;;;GAIG;AACH,KAAK,sBAAsB,CAAC,OAAO,SAAS,SAAS,MAAM,EAAE,EAAE,KAAK,SAAS,MAAM,IAAI,OAAO,SAAS,SAAS,EAAE,GAC9G,EAAE,GACF,OAAO,SAAS,SAAS,CAAC,MAAM,KAAK,SAAS,MAAM,EAAE,GAAG,MAAM,IAAI,SAAS,SAAS,MAAM,EAAE,CAAC,GAC5F,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,sBAAsB,CAAC,IAAI,EAAE,KAAK,CAAC,GAC3D,EAAE,CAAA;AAER,KAAK,oBAAoB,CAAC,CAAC,IAAI;KAC5B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK;CAC7D,CAAC,MAAM,CAAC,CAAC,CAAA;AAEV,KAAK,oBAAoB,CAAC,CAAC,IAAI;KAC5B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,cAAc,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC;CAC7D,CAAC,MAAM,CAAC,CAAC,CAAA;AAEV,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAAC,SAAS,cAAc,CAAC,MAAM,KAAK,CAAC,GAAG,KAAK,GAAG,KAAK,CAAA;AAEnF,KAAK,aAAa,CAAC,UAAU,EAAE,KAAK,SAAS,MAAM,IAAI,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,GACrF,EAAE,GACF,oBAAoB,CAAC,UAAU,CAAC,SAAS,KAAK,GAC5C;KAAG,CAAC,IAAI,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;CAAE,GAChE,oBAAoB,CAAC,UAAU,CAAC,SAAS,KAAK,GAC5C;KAAG,CAAC,IAAI,oBAAoB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;CAAE,GACtG;KAAG,CAAC,IAAI,oBAAoB,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;CAAE,GAAG;KAChF,CAAC,IAAI,oBAAoB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;CACnG,CAAA;AAGT,KAAK,OAAO,CAAC,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,EAAE,IAAI,KAAK,SAAS,CAAC,GACxD,GAAG,GACH,CAAC,SAAS,aAAa,CAAC,MAAM,KAAK,CAAC,GAClC,KAAK,GACL,CAAC,SAAS,YAAY,GACpB,MAAM,GACN,CAAC,SAAS,YAAY,GACpB,MAAM,GACN,CAAC,SAAS,aAAa,GACrB,OAAO,GACP,CAAC,SAAS,cAAc,GACtB,IAAI,GACJ,CAAC,SAAS,gBAAgB,GACxB,SAAS,GACT,CAAC,SAAS,SAAS,GACjB,GAAG,GACH,CAAC,SAAS,WAAW,CAAC,MAAM,IAAI,CAAC,GAC/B,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GACjC,CAAC,SAAS,YAAY,CAAC,MAAM,GAAG,EAAE,MAAM,KAAK,CAAC,GAC5C,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,WAAW,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAC5E,CAAC,SAAS,YAAY,CAAC,MAAM,UAAU,CAAC,GACtC,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC,GAChC,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAC/B,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,GACnC,CAAC,SAAS,kBAAkB,CAAC,MAAM,OAAO,CAAC,GACzC,sBAAsB,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAC5C,CAAC,SAAS,WAAW,CAAC,MAAM,OAAO,CAAC,GAClC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GACrC,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,CAAC,GAC/B,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GACvB,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAC3B,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GACnC,KAAK,CAAA;AAGvC,KAAK,IAAI,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,EAAE,GACtC,CAAC,GACD,CAAC,SAAS,CAAC,GACT,CAAC,GACD,CAAC,SAAS,CAAC,GACT,CAAC,GACD,CAAC,SAAS,CAAC,GACT,CAAC,GACD,CAAC,SAAS,CAAC,GACT,CAAC,GACD,CAAC,SAAS,CAAC,GACT,CAAC,GACD,CAAC,SAAS,CAAC,GACT,CAAC,GACD,CAAC,SAAS,CAAC,GACT,CAAC,GACD,CAAC,SAAS,CAAC,GACT,CAAC,GACD,CAAC,SAAS,CAAC,GACT,CAAC,GACD,CAAC,CAAA"}
|
package/package.json
CHANGED
package/src/coerce.test.ts
CHANGED
|
@@ -985,6 +985,26 @@ describe('intersection', () => {
|
|
|
985
985
|
extra: 'ok',
|
|
986
986
|
})
|
|
987
987
|
})
|
|
988
|
+
it('correctly picks the branch on an intersection with nested unions #1', () => {
|
|
989
|
+
const T = intersection([
|
|
990
|
+
union([object({ type: literal('a'), a: string() }), object({ type: literal('b'), b: string() })]),
|
|
991
|
+
object({ c: string() }),
|
|
992
|
+
])
|
|
993
|
+
expect(coerce(T, { type: 'a', a: 'x', c: 'y' })).toEqual({ type: 'a', a: 'x', c: 'y' })
|
|
994
|
+
expect(coerce(T, { type: 'b', b: 'x', c: 'y' })).toEqual({ type: 'b', b: 'x', c: 'y' })
|
|
995
|
+
expect(coerce(T, { c: 'y' })).toEqual({ type: 'a', a: '', c: 'y' })
|
|
996
|
+
})
|
|
997
|
+
it('correctly picks the branch on an intersection with nested unions #2', () => {
|
|
998
|
+
const T = intersection([
|
|
999
|
+
union([
|
|
1000
|
+
object({ type: literal('a'), a: optional(string()) }),
|
|
1001
|
+
object({ type: literal('b'), b: optional(string()) }),
|
|
1002
|
+
]),
|
|
1003
|
+
object({ c: optional(string()), d: optional(string()) }),
|
|
1004
|
+
])
|
|
1005
|
+
expect(coerce(T, { a: 'a' })).toEqual({ type: 'a', a: 'a' })
|
|
1006
|
+
expect(coerce(T, { a: 'a', c: 'c' })).toEqual({ type: 'a', a: 'a', c: 'c' })
|
|
1007
|
+
})
|
|
988
1008
|
})
|
|
989
1009
|
|
|
990
1010
|
describe('notDefined', () => {
|
package/src/schema.ts
CHANGED
|
@@ -74,7 +74,11 @@ export type OptionalSchema<S extends Schema> = {
|
|
|
74
74
|
schema: S
|
|
75
75
|
} & Documentation
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
/**
|
|
78
|
+
* `UnionSchema<any>` avoids a variance pitfall: `UnionSchema<[A, B]>` is not assignable to
|
|
79
|
+
* `UnionSchema<ObjectSchema<any>[]>`, which breaks `infer` when resolving `Static`.
|
|
80
|
+
*/
|
|
81
|
+
export type IntersectionSchema<Schemas extends readonly (ObjectSchema<any> | UnionSchema<any>)[]> = {
|
|
78
82
|
type: 'intersection'
|
|
79
83
|
schemas: Schemas
|
|
80
84
|
} & Documentation
|
|
@@ -117,7 +121,7 @@ export type Schema =
|
|
|
117
121
|
| ObjectSchema<Record<string, any>>
|
|
118
122
|
| UnionSchema<any[]>
|
|
119
123
|
| OptionalSchema<any>
|
|
120
|
-
| IntersectionSchema<readonly ObjectSchema<any>[]>
|
|
124
|
+
| IntersectionSchema<readonly (ObjectSchema<any> | UnionSchema<ObjectSchema<any>[]>)[]>
|
|
121
125
|
| LiteralSchema<any>
|
|
122
126
|
| LazySchema<any>
|
|
123
127
|
| EvaluateSchema<any>
|
|
@@ -194,7 +198,7 @@ const union = <Schemas extends Schema[]>(schemas: Schemas, options?: Documentati
|
|
|
194
198
|
typeComment: options?.typeComment,
|
|
195
199
|
})
|
|
196
200
|
|
|
197
|
-
const intersection = <Schemas extends readonly ObjectSchema<any>[]>(
|
|
201
|
+
const intersection = <const Schemas extends readonly (ObjectSchema<any> | UnionSchema<ObjectSchema<any>[]>)[]>(
|
|
198
202
|
schemas: Schemas,
|
|
199
203
|
options?: Documentation,
|
|
200
204
|
): IntersectionSchema<Schemas> => ({
|
package/src/types.ts
CHANGED
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
ObjectSchema,
|
|
13
13
|
OptionalSchema,
|
|
14
14
|
RecordSchema,
|
|
15
|
+
Schema,
|
|
15
16
|
StringSchema,
|
|
16
17
|
UnionSchema,
|
|
17
18
|
} from './schema'
|
|
@@ -19,13 +20,16 @@ import type {
|
|
|
19
20
|
// Export Static type with depth limit to prevent infinite recursion
|
|
20
21
|
export type Static<T> = _Static<T, 10>
|
|
21
22
|
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Folds intersection member schemas into an intersection of their static types.
|
|
25
|
+
* Uses `Schema` for tuple positions (not a narrower alias) so `infer First extends …` does not
|
|
26
|
+
* reject valid tuple elements and collapse to `{}`.
|
|
27
|
+
*/
|
|
28
|
+
type IntersectObjectStatics<Schemas extends readonly Schema[], Depth extends number> = Schemas extends readonly []
|
|
29
|
+
? {}
|
|
30
|
+
: Schemas extends readonly [infer First extends Schema, ...infer Rest extends readonly Schema[]]
|
|
31
|
+
? _Static<First, Depth> & IntersectObjectStatics<Rest, Depth>
|
|
32
|
+
: {}
|
|
29
33
|
|
|
30
34
|
type OptionalPropertyKeys<P> = {
|
|
31
35
|
[K in keyof P]: P[K] extends OptionalSchema<any> ? K : never
|
|
@@ -72,7 +76,7 @@ type _Static<T, Depth extends number = 10> = Depth extends 0
|
|
|
72
76
|
? ObjectStatics<Properties, Depth>
|
|
73
77
|
: T extends OptionalSchema<infer S>
|
|
74
78
|
? _Static<S, Prev<Depth>> | undefined
|
|
75
|
-
: T extends IntersectionSchema<infer Schemas
|
|
79
|
+
: T extends IntersectionSchema<infer Schemas>
|
|
76
80
|
? IntersectObjectStatics<Schemas, Prev<Depth>>
|
|
77
81
|
: T extends UnionSchema<infer Schemas>
|
|
78
82
|
? _Static<Schemas[number], Prev<Depth>>
|