@contember/typesafe
Advanced tools
Comparing version 1.2.0-alpha.2 to 1.2.0-alpha.3
@@ -35,4 +35,8 @@ declare type Unpacked<T> = T extends readonly (infer U)[] ? U : never; | ||
export declare const discriminatedUnion: <T extends Type<JsonObject>[]>(field: string, ...inner: T) => Type<ReturnType<Unpacked<T>>>; | ||
declare type TupleFromTupledType<T extends Type<Json>[]> = T extends [Type<infer X>, ...infer Y] ? Y extends Type<Json>[] ? readonly [X, ...TupleFromTupledType<Y>] : readonly [] : readonly []; | ||
declare type TupleFromTupledType<T extends Type<Json>[]> = T extends [Type<infer X>, ...infer Y] ? (Y extends Type<Json>[] ? readonly [X, ...TupleFromTupledType<Y>] : readonly []) : readonly []; | ||
export declare const tuple: <T extends Type<Json>[]>(...inner: T) => Type<TupleFromTupledType<T>>; | ||
declare type DiscriminatedTupleUnionType<T extends Record<string, Type<Json>[]>> = { | ||
[K in keyof T]: (readonly [K, ...TupleFromTupledType<T[K]>]); | ||
}[keyof T & string]; | ||
export declare const discriminatedTupleUnion: <T extends Record<string, Type<Json>[]>>(inner: T) => Type<DiscriminatedTupleUnionType<T>>; | ||
export declare const intersection: <T1 extends JsonObject, T2 extends JsonObject>(inner1: Type<T1>, inner2: Type<T2>) => Type<T1 & T2>; | ||
@@ -39,0 +43,0 @@ export declare const enumeration: <T extends string>(...values: T[]) => Type<T>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.valueAt = exports.coalesce = exports.transform = exports.nullable = exports.false_ = exports.true_ = exports.null_ = exports.enumeration = exports.intersection = exports.tuple = exports.discriminatedUnion = exports.union = exports.record = exports.partial = exports.object = exports.array = exports.literal = exports.anyJsonObject = exports.anyJson = exports.boolean = exports.number = exports.string = exports.fail = exports.ParseError = void 0; | ||
exports.valueAt = exports.coalesce = exports.transform = exports.nullable = exports.false_ = exports.true_ = exports.null_ = exports.enumeration = exports.intersection = exports.discriminatedTupleUnion = exports.tuple = exports.discriminatedUnion = exports.union = exports.record = exports.partial = exports.object = exports.array = exports.literal = exports.anyJsonObject = exports.anyJson = exports.boolean = exports.number = exports.string = exports.fail = exports.ParseError = void 0; | ||
const util_1 = require("util"); | ||
@@ -197,2 +197,4 @@ class ParseError extends Error { | ||
throw ParseError.format(input, path, 'array'); | ||
if (input.length !== inner.length) | ||
throw ParseError.format(input, path, `array with length ${inner.length}`); | ||
return Object.entries(inner).map(([k, v]) => { | ||
@@ -210,2 +212,22 @@ const newPath = [...path, k]; | ||
exports.tuple = tuple; | ||
const discriminatedTupleUnion = (inner) => { | ||
const type = (input, path = []) => { | ||
if (!Array.isArray(input)) | ||
throw ParseError.format(input, path, 'array'); | ||
if (input.length === 0) | ||
throw ParseError.format(input, path, `non-empty array`); | ||
const tupleType = inner[input[0]]; | ||
if (tupleType === undefined) | ||
throw ParseError.format(input, [...path, 0], `one of ${Object.keys(inner).join(', ')}`); | ||
if (input.length !== tupleType.length + 1) | ||
throw ParseError.format(input, path, `array with length ${tupleType.length + 1}`); | ||
for (let i = 0; i < tupleType.length; i++) { | ||
tupleType[i](input[i + 1], [...path, i + 1]); | ||
} | ||
return input; | ||
}; | ||
type.inner = inner; | ||
return type; | ||
}; | ||
exports.discriminatedTupleUnion = discriminatedTupleUnion; | ||
const intersection = (inner1, inner2) => { | ||
@@ -236,3 +258,7 @@ const type = (input, path = []) => { | ||
const nullable = (inner) => { | ||
return (0, exports.union)(exports.null_, inner); | ||
const type = (input, path = []) => { | ||
return input === null ? input : inner(input, path); | ||
}; | ||
type.inner = inner; | ||
return type; | ||
}; | ||
@@ -239,0 +265,0 @@ exports.nullable = nullable; |
{ | ||
"name": "@contember/typesafe", | ||
"version": "1.2.0-alpha.2", | ||
"version": "1.2.0-alpha.3", | ||
"license": "Apache-2.0", | ||
@@ -11,7 +11,7 @@ "main": "dist/src/index.js", | ||
"dependencies": { | ||
"@contember/schema": "^1.2.0-alpha.2" | ||
"@contember/schema": "^1.2.0-alpha.3" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^17.0.5" | ||
"@types/node": "^16" | ||
} | ||
} |
@@ -221,4 +221,5 @@ import { isDeepStrictEqual } from 'util' | ||
type TupleFromTupledType<T extends Type<Json>[]> = T extends [Type<infer X>, ...infer Y] ? | ||
Y extends Type<Json>[] ? readonly [X, ...TupleFromTupledType<Y>] : readonly [] : readonly [] | ||
type TupleFromTupledType<T extends Type<Json>[]> = T extends [Type<infer X>, ...infer Y] | ||
? (Y extends Type<Json>[] ? readonly [X, ...TupleFromTupledType<Y>] : readonly []) | ||
: readonly [] | ||
@@ -228,2 +229,3 @@ export const tuple = <T extends Type<Json>[]>(...inner: T): Type<TupleFromTupledType<T>> => { | ||
if (!Array.isArray(input)) throw ParseError.format(input, path, 'array') | ||
if (input.length !== inner.length) throw ParseError.format(input, path, `array with length ${inner.length}`) | ||
return Object.entries(inner).map(([k, v]) => { | ||
@@ -243,2 +245,26 @@ const newPath = [...path, k] | ||
type DiscriminatedTupleUnionType<T extends Record<string, Type<Json>[]>> = | ||
{ [K in keyof T]: (readonly [K, ...TupleFromTupledType<T[K]>]) }[keyof T & string] | ||
export const discriminatedTupleUnion = <T extends Record<string, Type<Json>[]>>(inner: T): Type<DiscriminatedTupleUnionType<T>> => { | ||
const type = (input: unknown, path: PropertyKey[] = []): DiscriminatedTupleUnionType<T> => { | ||
if (!Array.isArray(input)) throw ParseError.format(input, path, 'array') | ||
if (input.length === 0) throw ParseError.format(input, path, `non-empty array`) | ||
const tupleType = inner[input[0]] | ||
if (tupleType === undefined) throw ParseError.format(input, [...path, 0], `one of ${Object.keys(inner).join(', ')}`) | ||
if (input.length !== tupleType.length + 1) throw ParseError.format(input, path, `array with length ${tupleType.length + 1}`) | ||
for (let i = 0; i < tupleType.length; i++) { | ||
tupleType[i](input[i + 1], [...path, i + 1]) | ||
} | ||
return input as any | ||
} | ||
type.inner = inner | ||
return type | ||
} | ||
export const intersection = <T1 extends JsonObject, T2 extends JsonObject>(inner1: Type<T1>, inner2: Type<T2>): Type<T1 & T2> => { | ||
@@ -271,3 +297,8 @@ const type = (input: unknown, path: PropertyKey[] = []): T1 & T2 => { | ||
export const nullable = <T extends Json>(inner: Type<T>): Type<T | null> => { | ||
return union(null_, inner) | ||
const type = (input: unknown, path: PropertyKey[] = []) => { | ||
return input === null ? input : inner(input, path) | ||
} | ||
type.inner = inner | ||
return type | ||
} | ||
@@ -274,0 +305,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
67920
642