@contember/typesafe 2.1.0-alpha.9 → 2.1.0-beta.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/dist/development/index.cjs +19 -15
- package/dist/development/index.cjs.map +1 -1
- package/dist/development/index.js +19 -15
- package/dist/development/index.js.map +1 -1
- package/dist/production/index.cjs +19 -15
- package/dist/production/index.cjs.map +1 -1
- package/dist/production/index.js +19 -15
- package/dist/production/index.js.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -3
- package/src/index.ts +38 -33
package/src/index.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type Json =
|
|
|
13
13
|
| readonly Json[]
|
|
14
14
|
| JsonObject
|
|
15
15
|
|
|
16
|
-
export interface Type<T extends Json | {readonly [K in string]?: Json} | undefined = Json> {
|
|
16
|
+
export interface Type<T extends Json | { readonly [K in string]?: Json } | undefined = Json> {
|
|
17
17
|
(input: unknown, path?: PropertyKey[]): T
|
|
18
18
|
readonly inner?: any
|
|
19
19
|
}
|
|
@@ -60,7 +60,6 @@ export const boolean = ((): Type<boolean> => {
|
|
|
60
60
|
}
|
|
61
61
|
})()
|
|
62
62
|
|
|
63
|
-
|
|
64
63
|
export const scalar = ((): Type<Scalar> => {
|
|
65
64
|
return (input: unknown, path: PropertyKey[] = []): Scalar => {
|
|
66
65
|
if (input === null) {
|
|
@@ -109,9 +108,11 @@ export const anyJson = ((): Type<Json> => {
|
|
|
109
108
|
export const anyJsonObject = ((): Type<JsonObject> => {
|
|
110
109
|
return (input: unknown, path: PropertyKey[] = []): JsonObject => {
|
|
111
110
|
if (input === null || typeof input !== 'object') throw ParseError.format(input, path, 'object')
|
|
112
|
-
return Object.fromEntries(
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
return Object.fromEntries(
|
|
112
|
+
Object.entries(input).map(([key, value]) => {
|
|
113
|
+
return [key, anyJson(value, [...path, key])]
|
|
114
|
+
}),
|
|
115
|
+
)
|
|
115
116
|
}
|
|
116
117
|
})()
|
|
117
118
|
|
|
@@ -160,17 +161,19 @@ export const object = <T extends Record<string, Type<Json>>>(inner: T): Type<{ r
|
|
|
160
161
|
export const partial = <T extends Record<string, Type<Json | undefined>>>(inner: T) => {
|
|
161
162
|
const type = (input: unknown, path: PropertyKey[] = []): { readonly [P in keyof T]?: Exclude<ReturnType<T[P]>, undefined> } => {
|
|
162
163
|
if (input === null || typeof input !== 'object') throw ParseError.format(input, path, 'object')
|
|
163
|
-
return Object.fromEntries(
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
164
|
+
return Object.fromEntries(
|
|
165
|
+
Object.entries(inner ?? {}).flatMap(([k, v]) => {
|
|
166
|
+
const newPath = [...path, k]
|
|
167
|
+
if (!(k in (input as object)) || (input as any)[k] === undefined) {
|
|
168
|
+
return []
|
|
169
|
+
}
|
|
170
|
+
const val = v((input as any)[k], newPath)
|
|
171
|
+
if (val === undefined) {
|
|
172
|
+
return []
|
|
173
|
+
}
|
|
174
|
+
return [[k, val]]
|
|
175
|
+
}),
|
|
176
|
+
) as any
|
|
174
177
|
}
|
|
175
178
|
|
|
176
179
|
type.inner = inner
|
|
@@ -181,7 +184,7 @@ export const partial = <T extends Record<string, Type<Json | undefined>>>(inner:
|
|
|
181
184
|
export const noExtraProps = <T extends JsonObject>(inner: Type<T>) => {
|
|
182
185
|
const type = (input: unknown, path: PropertyKey[] = []): T => {
|
|
183
186
|
const result = inner(input, path)
|
|
184
|
-
if (!(typeof input === 'object' &&
|
|
187
|
+
if (!(typeof input === 'object' && input !== null && typeof result === 'object' && result !== null)) {
|
|
185
188
|
return result
|
|
186
189
|
}
|
|
187
190
|
const resultProps = new Set(Object.keys(result))
|
|
@@ -198,7 +201,6 @@ export const noExtraProps = <T extends JsonObject>(inner: Type<T>) => {
|
|
|
198
201
|
return type
|
|
199
202
|
}
|
|
200
203
|
|
|
201
|
-
|
|
202
204
|
export const record = <K extends Type<string>, T extends Type<Json>>(key: K, value: T): Type<{ readonly [P in ReturnType<K>]: ReturnType<T> }> => {
|
|
203
205
|
const type = (input: unknown, path: PropertyKey[] = []): { readonly [P in ReturnType<K>]: ReturnType<T> } => {
|
|
204
206
|
if (input === null || typeof input !== 'object') {
|
|
@@ -217,7 +219,6 @@ export const record = <K extends Type<string>, T extends Type<Json>>(key: K, val
|
|
|
217
219
|
return type
|
|
218
220
|
}
|
|
219
221
|
|
|
220
|
-
|
|
221
222
|
export const union = <T extends Type<Json>[]>(...inner: T): Type<ReturnType<Unpacked<T>>> => {
|
|
222
223
|
const type = (input: unknown, path: PropertyKey[] = []): ReturnType<Unpacked<T>> => {
|
|
223
224
|
const errors = []
|
|
@@ -277,7 +278,10 @@ export const partiallyDiscriminatedUnion = <T extends Type<JsonObject>[]>(field:
|
|
|
277
278
|
return type
|
|
278
279
|
}
|
|
279
280
|
|
|
280
|
-
export const discriminatedUnion = <F extends string, T extends {[key: string]: JsonObject}>(
|
|
281
|
+
export const discriminatedUnion = <F extends string, T extends { [key: string]: JsonObject }>(
|
|
282
|
+
field: F,
|
|
283
|
+
inner: { [K in keyof T]: Type<T[K]> },
|
|
284
|
+
): Type<{ [K in keyof T]: { [X in F]: K } & T[K] }[keyof T]> => {
|
|
281
285
|
const type = (input: unknown, path: PropertyKey[] = []): { [K in keyof T]: { [X in F]: K } & T[K] }[keyof T] => {
|
|
282
286
|
if (input === null || typeof input !== 'object') throw ParseError.format(input, path, 'object')
|
|
283
287
|
const key = (input as any)[field]
|
|
@@ -289,7 +293,6 @@ export const discriminatedUnion = <F extends string, T extends {[key: string]: J
|
|
|
289
293
|
const { [field]: _, ...inputWithoutDiscr } = input
|
|
290
294
|
|
|
291
295
|
return { [field]: key, ...discriminatedType(inputWithoutDiscr, path) }
|
|
292
|
-
|
|
293
296
|
}
|
|
294
297
|
type.inner = inner
|
|
295
298
|
|
|
@@ -318,8 +321,9 @@ export const tuple = <T extends Type<Json>[]>(...inner: T): Type<TupleFromTupled
|
|
|
318
321
|
return type
|
|
319
322
|
}
|
|
320
323
|
|
|
321
|
-
type DiscriminatedTupleUnionType<T extends Record<string, Type<Json>[]>> =
|
|
322
|
-
|
|
324
|
+
type DiscriminatedTupleUnionType<T extends Record<string, Type<Json>[]>> = {
|
|
325
|
+
[K in keyof T]: (readonly [K, ...TupleFromTupledType<T[K]>])
|
|
326
|
+
}[keyof T & string]
|
|
323
327
|
|
|
324
328
|
export const discriminatedTupleUnion = <T extends Record<string, Type<Json>[]>>(inner: T): Type<DiscriminatedTupleUnionType<T>> => {
|
|
325
329
|
const type = (input: unknown, path: PropertyKey[] = []): DiscriminatedTupleUnionType<T> => {
|
|
@@ -377,13 +381,16 @@ export const nullable = <T extends Json>(inner: Type<T>): Type<T | null> => {
|
|
|
377
381
|
return type
|
|
378
382
|
}
|
|
379
383
|
|
|
380
|
-
export const preprocess =
|
|
381
|
-
|
|
382
|
-
|
|
384
|
+
export const preprocess =
|
|
385
|
+
<Input extends Json>(inner: Type<Input>, transform: (input: unknown) => unknown) => (input: unknown, path: PropertyKey[] = []): Input => {
|
|
386
|
+
return inner(transform(input), path)
|
|
387
|
+
}
|
|
383
388
|
|
|
384
|
-
export const transform =
|
|
385
|
-
|
|
386
|
-
|
|
389
|
+
export const transform =
|
|
390
|
+
<Input extends Json, Result extends Json>(inner: Type<Input>, transform: (value: Input, input: unknown, path: PropertyKey[]) => Result) =>
|
|
391
|
+
(input: unknown, path: PropertyKey[] = []): Result => {
|
|
392
|
+
return transform(inner(input, path), input, path)
|
|
393
|
+
}
|
|
387
394
|
|
|
388
395
|
export const coalesce = <T extends Json, F extends Json>(inner: Type<T>, fallback: F): Type<T | F> => {
|
|
389
396
|
const type = (input: unknown, path: PropertyKey[] = []): T | F => {
|
|
@@ -406,12 +413,10 @@ export const valueAt = (input: any, path: PropertyKey[]): unknown | undefined =>
|
|
|
406
413
|
return value
|
|
407
414
|
}
|
|
408
415
|
|
|
409
|
-
type EqualsWrapped<T> = T extends infer R & {}
|
|
410
|
-
? {
|
|
416
|
+
type EqualsWrapped<T> = T extends infer R & {} ? {
|
|
411
417
|
[P in keyof R]: R[P]
|
|
412
418
|
}
|
|
413
419
|
: never
|
|
414
420
|
|
|
415
|
-
export type Equals<A, B> = (<T>() => T extends EqualsWrapped<A> ? 1 : 2) extends <T>() => T extends EqualsWrapped<B> ? 1 : 2
|
|
416
|
-
? true
|
|
421
|
+
export type Equals<A, B> = (<T>() => T extends EqualsWrapped<A> ? 1 : 2) extends <T>() => T extends EqualsWrapped<B> ? 1 : 2 ? true
|
|
417
422
|
: false
|