diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 1ffc372a..0c7d8ee0 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -8,6 +8,7 @@ export { IfDefined, memoize, memoizeWithKey, + Selector, UnknownIfNever, unsupportedAdapter, } from './utils'; diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index 16760479..f498bb9b 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -47,3 +47,15 @@ export function unsupportedAdapter( throw new Error(`This feature is unsupported for ${adapterName}`); }; } + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export interface Selector> { + value: T[keyof T]; + kind: keyof T; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + fn: any}>( + map: TMap, + ) => ( + value: U, + ) => ReturnType; +} diff --git a/packages/main/src/resolver.ts b/packages/main/src/resolver.ts index 81163f47..15c1e898 100644 --- a/packages/main/src/resolver.ts +++ b/packages/main/src/resolver.ts @@ -1,5 +1,5 @@ import type {AdapterResolvers} from './adapters'; -import type {Select} from './selector'; +import type {SchemaKind} from './selector'; import type { InputFrom, OutputFrom, @@ -11,6 +11,12 @@ export interface AdapterResolver extends Resolver { base: { [TModule in keyof AdapterResolvers]: SchemaFrom; }[keyof AdapterResolvers]; - input: InputFrom], this['schema']>; - output: OutputFrom], this['schema']>; + input: InputFrom< + AdapterResolvers[SchemaKind], + this['schema'] + >; + output: OutputFrom< + AdapterResolvers[SchemaKind], + this['schema'] + >; } diff --git a/packages/main/src/selector.ts b/packages/main/src/selector.ts index 683e4a13..e86a110f 100644 --- a/packages/main/src/selector.ts +++ b/packages/main/src/selector.ts @@ -1,7 +1,7 @@ import type {AdapterResolvers} from './adapters'; import type {AdapterResolver} from './resolver'; import type {Kind} from '@sinclair/typebox'; -import type {IfDefined, SchemaFrom} from '@typeschema/core'; +import type {IfDefined, SchemaFrom, Selector} from '@typeschema/core'; import type {CoreValidator} from 'suretype'; type IsTypeboxSchema = [IfDefined] extends [never] @@ -48,54 +48,37 @@ function notJSON( return schema as any; } -export type Select = - // eslint-disable-next-line @typescript-eslint/ban-types - TSchema extends Function - ? TSchema extends {assert: unknown} - ? 'arktype' - : IsClassValidatorSchema extends true - ? 'classValidator' - : 'function' - : IsTypeboxSchema extends true - ? 'typebox' - : IsSuretypeSchema extends true - ? 'suretype' - : TSchema extends {__isYupSchema__: unknown} - ? 'yup' - : TSchema extends {_def: unknown} - ? 'zod' - : TSchema extends {async: unknown} - ? 'valibot' - : TSchema extends {refiner: unknown} - ? 'superstruct' - : TSchema extends {_flags: unknown} - ? 'joi' - : TSchema extends {encode: unknown} - ? 'ioTs' - : TSchema extends {reflect: unknown} - ? 'runtypes' - : TSchema extends {ast: unknown} - ? 'effect' - : TSchema extends {kind: unknown} - ? 'deepkit' - : TSchema extends {addValidator: unknown} - ? 'ow' - : TSchema extends {toTerminals: unknown} - ? 'valita' - : 'json'; +interface SchemaSelector + extends Selector<{ + [TModule in keyof AdapterResolvers]: SchemaFrom; + }> { + // prettier-ignore + kind: + // eslint-disable-next-line @typescript-eslint/ban-types + this['value'] extends Function + ? this['value'] extends {assert: unknown} ? 'arktype' + : IsClassValidatorSchema extends true ? 'classValidator' + : 'function' + : this['value'] extends object + ? IsTypeboxSchema extends true ? 'typebox' + : IsSuretypeSchema extends true ? 'suretype' + : this['value'] extends {__isYupSchema__: unknown} ? 'yup' + : this['value'] extends {_def: unknown} ? 'zod' + : this['value'] extends {async: unknown} ? 'valibot' + : this['value'] extends {refiner: unknown} ? 'superstruct' + : this['value'] extends {_flags: unknown} ? 'joi' + : this['value'] extends {encode: unknown} ? 'ioTs' + : this['value'] extends {reflect: unknown} ? 'runtypes' + : this['value'] extends {ast: unknown} ? 'effect' + : this['value'] extends {kind: unknown} ? 'deepkit' + : this['value'] extends {addValidator: unknown} ? 'ow' + : this['value'] extends {toTerminals: unknown} ? 'valita' + : 'json' + : never; +} +export type SchemaKind = (SchemaSelector & {value: T})['kind']; -export const select: < - TMap extends { - [TModule in keyof AdapterResolvers]: ( - schema: SchemaFrom, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ) => any; - }, ->( - is: TMap, -) => >( - schema: TSchema, -) => ReturnType]> = +export const select: SchemaSelector['fn'] = /* @__NO_SIDE_EFFECTS__ */ is => schema => { switch (typeof schema) {