A
arktype•4mo ago
Dimava

Type Magic: validation on type property

How to validate defs in object type properties?
export type validateSchema<
def,
schema,
> = {
[K in keyof schema]:
K extends keyof def
? validateTypeRoot<def[K]>
: validateTypeRoot<unknown>
}

function test<const def>(
def: validateSchema<def, { a: 1 }>,
) { }

test({
a: 'str',
})
export type validateSchema<
def,
schema,
> = {
[K in keyof schema]:
K extends keyof def
? validateTypeRoot<def[K]>
: validateTypeRoot<unknown>
}

function test<const def>(
def: validateSchema<def, { a: 1 }>,
) { }

test({
a: 'str',
})
I did that three days ago but I forgot how
20 Replies
Dimava
Dimava•4mo ago
Apparently I need to use keyof def somewhere
export type validateSchema<
def,
schema,
> = show<{
[K in keyof schema & keyof def]:
| equals<Required<schema>[K], Type> extends true
? validateTypeRoot<def[K]>
: conform<def[K], schema[K]>
} & {
[K in keyof schema as K extends keyof def ? never : K]:
| schema[K]
}>

function test<const def>(
def: validateSchema<def, {
body: Type
response: Type
statusCode: number
}>,
) { }

test({
body: 'string',
response: 'number',
statusCode: 200
})
export type validateSchema<
def,
schema,
> = show<{
[K in keyof schema & keyof def]:
| equals<Required<schema>[K], Type> extends true
? validateTypeRoot<def[K]>
: conform<def[K], schema[K]>
} & {
[K in keyof schema as K extends keyof def ? never : K]:
| schema[K]
}>

function test<const def>(
def: validateSchema<def, {
body: Type
response: Type
statusCode: number
}>,
) { }

test({
body: 'string',
response: 'number',
statusCode: 200
})
ssalbdivad
ssalbdivad•4mo ago
What is the point of this just so you don't have to write "200" instead of 200?
Dimava
Dimava•4mo ago
I want to validate an arbitrary definition schema with Type definitions on random predefined places Does not have to be specifically ArkType definitions Hah, there may be some booleans and object configs which are unrelated to definitions@ssalbdivad
ssalbdivad
ssalbdivad•4mo ago
Sounds like it would be unnecessary once I support metadata
Dimava
Dimava•4mo ago
e.g. if I'd want to have an Elysia config that has format
// the properties that are definitions
export interface InputSchema<Name extends string = string> {
body?: TSchema | Name
headers?: TObject | Name
query?: TObject | Name
params?: TObject | Name
cookie?: TObject | Name
response?:
| TSchema
| Record<number, TSchema>
| Name
| Record<number, Name | TSchema>
}

export type LocalHook<
LocalSchema extends InputSchema,
Schema extends RouteSchema,
Singleton extends SingletonBase,
Errors extends Record<string, Error>,
Extension extends BaseMacro,
Path extends string = '',
TypedRoute extends RouteSchema
> = LocalSchema & Extension & {
// the rest
type?: ContentType
detail?: DocumentDecoration
parse?: MaybeArray<BodyHandler<TypedRoute, Singleton>>
transform?: MaybeArray<TransformHandler<TypedRoute, Singleton>>
beforeHandle?: MaybeArray<OptionalHandler<TypedRoute, Singleton>>
afterHandle?: MaybeArray<AfterHandler<TypedRoute, Singleton>>
mapResponse?: MaybeArray<MapResponse<TypedRoute, Singleton>>
error?: MaybeArray<ErrorHandler<Errors, TypedRoute, Singleton>>
onResponse?: MaybeArray<VoidHandler<TypedRoute, Singleton>>
tags?: DocumentDecoration['tags']
}
// the properties that are definitions
export interface InputSchema<Name extends string = string> {
body?: TSchema | Name
headers?: TObject | Name
query?: TObject | Name
params?: TObject | Name
cookie?: TObject | Name
response?:
| TSchema
| Record<number, TSchema>
| Name
| Record<number, Name | TSchema>
}

export type LocalHook<
LocalSchema extends InputSchema,
Schema extends RouteSchema,
Singleton extends SingletonBase,
Errors extends Record<string, Error>,
Extension extends BaseMacro,
Path extends string = '',
TypedRoute extends RouteSchema
> = LocalSchema & Extension & {
// the rest
type?: ContentType
detail?: DocumentDecoration
parse?: MaybeArray<BodyHandler<TypedRoute, Singleton>>
transform?: MaybeArray<TransformHandler<TypedRoute, Singleton>>
beforeHandle?: MaybeArray<OptionalHandler<TypedRoute, Singleton>>
afterHandle?: MaybeArray<AfterHandler<TypedRoute, Singleton>>
mapResponse?: MaybeArray<MapResponse<TypedRoute, Singleton>>
error?: MaybeArray<ErrorHandler<Errors, TypedRoute, Singleton>>
onResponse?: MaybeArray<VoidHandler<TypedRoute, Singleton>>
tags?: DocumentDecoration['tags']
}
where half of properties are definitions and half are not
ssalbdivad
ssalbdivad•4mo ago
I would probably just list the keys you want to be treated as type defs in a tuple since you'll need that logic to know what to parse at runtime anyways And you can infer the type from it and use that to select which are validated as definitions
Dimava
Dimava•4mo ago
You mean like [body, headers, query, ...]?
ssalbdivad
ssalbdivad•4mo ago
Yeah in strings
Dimava
Dimava•4mo ago
Nah they all are optional
ssalbdivad
ssalbdivad•4mo ago
That doesn't matter
Dimava
Dimava•4mo ago
what's that ah Hmm Anyways I got it to work so it's fine now
ssalbdivad
ssalbdivad•4mo ago
body: Type and equals<Required<schema>[K], Type is a crazy way to do this Your call I suppose
Dimava
Dimava•4mo ago
That looks cool in optional autocompletion 🤔 Tho maybe I could equals to "type" and morph it to Type
ssalbdivad
ssalbdivad•4mo ago
How can something look cool in autocompletion haha
Dimava
Dimava•4mo ago
No description
Want results from more Discord servers?
Add your server