Skip to content
Permalink
Browse files

feat: joi typings with IN and OUT types

  • Loading branch information...
kirillgroshkov committed May 18, 2019
1 parent f177f71 commit 8ab6ccff68d791622e73ba99f845af1f224a6b40
@@ -12,20 +12,24 @@ import {
StringSchema,
} from '@hapi/joi'

export type SchemaTyped<T> =
| AnySchemaT<T>
| ArraySchemaTyped<T>
| AlternativesSchemaTyped<T>
export type SchemaTyped<IN, OUT = IN> =
| AnySchemaT<IN, OUT>
| ArraySchemaTyped<IN>
| AlternativesSchemaTyped<IN>
| BinarySchemaTyped
| BooleanSchemaTyped
| DateSchemaTyped<T>
| FunctionSchemaTyped<T>
| DateSchemaTyped<IN>
| FunctionSchemaTyped<IN>
| NumberSchemaTyped
| ObjectSchemaTyped<T>
| ObjectSchemaTyped<IN, OUT>
| StringSchemaTyped
| LazySchemaTyped<T>
| LazySchemaTyped<IN>

export interface AnySchemaT<T> extends AnySchema {}
/**
* IN - value before validation/conversion
* OUT - value after validation/conversion (can be different due to conversion, stripping, etc)
*/
export interface AnySchemaT<IN, OUT = IN> extends AnySchema {}

export interface ArraySchemaTyped<T> extends ArraySchema, AnySchemaT<T[]> {}
export interface AlternativesSchemaTyped<T> extends AlternativesSchema {}
@@ -34,6 +38,6 @@ export interface BooleanSchemaTyped extends BooleanSchema, AnySchemaT<boolean> {
export interface DateSchemaTyped<T> extends DateSchema {}
export interface FunctionSchemaTyped<T> extends FunctionSchema {}
export interface NumberSchemaTyped extends NumberSchema, AnySchemaT<number> {}
export interface ObjectSchemaTyped<T> extends ObjectSchema, AnySchemaT<T> {}
export interface ObjectSchemaTyped<IN, OUT> extends ObjectSchema, AnySchemaT<IN, OUT> {}
export interface StringSchemaTyped extends StringSchema, AnySchemaT<string> {}
export interface LazySchemaTyped<T> extends LazySchema {}
@@ -9,13 +9,13 @@ export const integerSchema = Joi.number().integer()
export const dateStringSchema = stringSchema.dateString()
export const binarySchema = Joi.binary()

export function arraySchema<T> (items?: AnySchemaT<T>): ArraySchemaTyped<T> {
export function arraySchema<T> (items?: AnySchemaT<T, T>): ArraySchemaTyped<T> {
return items ? Joi.array().items(items) : Joi.array()
}

export function objectSchema<T> (
schema?: { [key in keyof T]: AnySchemaT<T[key]> },
): ObjectSchemaTyped<T> {
export function objectSchema<IN, OUT = IN> (
schema?: { [key in keyof IN]: AnySchemaT<IN[key]> },
): ObjectSchemaTyped<IN, OUT> {
return Joi.object(schema)
}

@@ -41,13 +41,18 @@ const defaultOptions: ValidationOptions = {
*
* If `schema` is undefined - returns value as is.
*/
export function validate<T> (
value: T,
schema?: AnySchemaT<T>,
export function validate<IN, OUT = IN> (
value: IN,
schema?: AnySchemaT<IN, OUT>,
objectName?: string,
options: ValidationOptions = {},
): T {
const { value: returnValue, error } = getValidationResult(value, schema, objectName, options)
): OUT {
const { value: returnValue, error } = getValidationResult<IN, OUT>(
value,
schema,
objectName,
options,
)

if (error) {
throw error
@@ -63,21 +68,21 @@ export function validate<T> (
*
* If `schema` is undefined - returns value as is.
*/
export function getValidationResult<T> (
value: T,
schema?: AnySchemaT<T>,
export function getValidationResult<IN, OUT = IN> (
value: IN,
schema?: AnySchemaT<IN, OUT>,
objectName?: string,
options: ValidationOptions = {},
): JoiValidationResult<T> {
if (!schema) return { value }
): JoiValidationResult<OUT> {
if (!schema) return { value } as any

const { value: returnValue, error } = Joi.validate(value, schema, {
...defaultOptions,
...options,
})

const vr: JoiValidationResult<T> = {
value: returnValue,
const vr: JoiValidationResult<OUT> = {
value: (returnValue as any) as OUT,
}

if (error) {

0 comments on commit 8ab6ccf

Please sign in to comment.
You can’t perform that action at this time.