Issue
I’ve got a decorator:
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor): void {
const originalMethod = descriptor.value
if (!schema) return originalMethod
schema(types)
descriptor.value = function (...args: any[]) {
return originalMethod.apply(this, args)
}
}
and I initiate the schema like this:
@endpoint({
schema: (types) => ({
test: 'test',
test2: 'test2',
})
})
I always need to assign the type:
Is it possible to somehow specify it may be in the decorator or any other way to avoid it without using // @ts-ignore
UPDATE
This is the decorator declaration
export function endpoint({ schema }: { schema: any, path?: string }) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor): void {
const types: any = Joi.types()
const originalMethod = descriptor.value
if (!schema) return originalMethod
descriptor.value = function (...args: any[]) {
const context: any = { ...this, ...target, methodName: propertyKey }
try {
const { error } = schema.call(context, types, Joi).validate(args[0], { abortEarly: false })
if(error) {
return {
type: 'ValidationError',
code: 422,
errors: error.details.map((err: any) => err.message)
}
}
} catch(err: any) {
return {
type: 'InternalError',
code: 500,
errors: err.message,
}
}
return originalMethod.apply(this, args)
}
}
}
I’m using it like this at the moment, where I always need to provide the type, but I would like to just do like this to save time because I already know what type there should be 100% and maybe there is an option to set the type as a predefined one for that particular place.
It would sure make the code shorter and faster dev experience
@endpoint({
schema: ({ object, string }: any) => object.keys({
name: string,
description: string,
category: string.optional(),
})
})
Link where you can find the playground with the main idea
Solution
You don’t typically need to type callback function arguments manually, but in this case you have many things here typed as any
which should not be.
If you type schema
properly, everything seems to work very well.
I don’t know Joi
at all, but I derived the following type for the schema
function from your example:
type SchemaFn = (
types: ReturnType<typeof Joi['types']>,
joi: typeof Joi
) => Joi.ObjectSchema<any>
Which you can then use like so:
function endpoint({ schema }: { schema: SchemaFn, path?: string }) {
//...
}
With that, this code has no type errors.
class Test {
@endpoint({
schema: ({ object, string }) => object.keys({
a: string.max(10),
b: string.optional(),
})
})
testMe() {
return {
type: `Cool`,
message: `Ok`,
code: 200,
}
}
}
And even better than having no errors, object
and string
here are strongly typed. So you get intellisense and type checking on your usage of those values.
Answered By – Alex Wayne
Answer Checked By – Jay B. (AngularFixing Admin)