GoogleFeud / ts-runtime-checks

A typescript transformer that automatically generates validation code from your types.
https://googlefeud.github.io/ts-runtime-checks/
MIT License
312 stars 7 forks source link

[BUG] #44

Closed dyushin closed 4 months ago

dyushin commented 11 months ago

Hello. I have confused with this situation.

Lets have this generic function

import { Response, Request, NextFunction } from "express"

export function endpoint<Body = {}, Params = {}, Query = {}>(
    ...fns: ((
        req: Request<Params, any, Body, Query>,
        res: Response,
        next: NextFunction
    ) => Promise<any> | any)[]
) {
    const f = fns.pop()!
    const middlewares = fns
    return [
        ...middlewares,
        async (
            req: Request<Params, any, Body, Query>,
            res: Response,
            next: NextFunction
        ) => {
            try {
                let [body, bodyValidationErrors] = check<Infer<Body>>(req.body)
                if (bodyValidationErrors.length)
                    throw new Error(bodyValidationErrors.join(", "))
                await f(req, res, next)
            } catch (e: unknown) {
                next(e)
            }
        },
    ]
}

This is how i want use it /routes/content/[gameId].ts

export const get = endpoint<{}>(authorizedOnly, async (req, res) => {
    res.json(req.params)
})

export const post = endpoint<{ saveDate: string; data: string }>(
    authorizedOnly,
    async (req, res) => {
        res.json(req.params)
    }
)

I expect the post function call will not work without body{saveDate,data} but it works because of in get function body can be empty and after transpilation all validation code is merged it one function endpoint

Is it possible to isolate types for each separate function?

GoogleFeud commented 11 months ago

Sadly no, this is currently impossible to do. You can use the Resolve type, but that will return a single error instead of all of them like how it is currently in your code.

I think I'll be adding something that fixes this soon, though!