arb / celebrate

A joi validation middleware for Express.
MIT License
1.34k stars 65 forks source link

Typescript inference from arguments #212

Closed ghost closed 3 years ago

ghost commented 3 years ago

I am concerned with the celebrate function typing. Any reason why you would not want to infer typing from arguments ? I see several benefits:

It would be better if celebrate inferred req.body type directly from the body argument. Same for query or params.

I had it working with the following fix:

export interface SchemaOptions<P=ParamsDictionary, ReqBody=any, ReqQuery=Query> {
    /**
     * When `params` is set, `joi` will validate `req.params` with the supplied schema.
     */
    params?: Joi.Schema<P>;
    /**
     * When `headers` is set, `joi` will validate `req.headers` with the supplied schema.
     */
    headers?: object;
    /**
     * When `query` is set, `joi` will validate `req.query` with the supplied schema.
     */
    query?: Joi.Schema<ReqQuery>;
    /**
     * When `cookies` is set, `joi` will validate `req.cookies` with the supplied schema.
     */
    cookies?: object;
    /**
     * When `signedCookies` is set, `joi` will validate `req.signedCookies` with the supplied schema.
     */
    signedCookies?: object;
    /**
     * When `body` is set, `joi` will validate `req.body` with the supplied schema.
     */
    body?: Joi.Schema<ReqBody>;
}

/**
* Creates a celebrate middleware function.
*/
export declare function celebrate<P=ParamsDictionary, ResBody=any, ReqBody=any, ReqQuery=Query>(requestRules: SchemaOptions<P, ReqBody, ReqQuery>, joiOpts?: ValidationOptions, opts?: CelebrateOptions): RequestHandler<P, ResBody, ReqBody, ReqQuery>;

You can see in the attached picture that typing is inferred correctly based on body arguments provided.

Only downside: I had to make a small change to Joi types, to make Joi.Schema generic for ObjectSchema. But it should be very easy to make this change accepted because it's a seamless change:


// From this
    type Schema =
        | AnySchema
        | ArraySchema
        | AlternativesSchema
        | BinarySchema
        | BooleanSchema
        | DateSchema
        | FunctionSchema
        | NumberSchema
        | ObjectSchema
        | StringSchema
        | LinkSchema
        | SymbolSchema;

// to this
    type Schema<P = any> =
        | AnySchema
        | ArraySchema
        | AlternativesSchema
        | BinarySchema
        | BooleanSchema
        | DateSchema
        | FunctionSchema
        | NumberSchema
        | ObjectSchema<P>
        | StringSchema
        | LinkSchema
        | SymbolSchema;

image

Are you interested in a PR with those changes ?

ghost commented 3 years ago

I created the PR in joi repo

ghost commented 3 years ago

Why would you close ? Joi juste merged my PR, I will create a celebrate PR for this issue.

arb commented 3 years ago

I closed this because I thought the only change needed to happen was in Joi, which landed.

outranker commented 1 year ago

Can we reopen this issue? I am going to create a PR for this. I think this will be very useful feature