'What is the best way to automatically validate requests using Typescript?

I would like to use Typescript interfaces to easily validate backend requests. Is there a way to make it happen? Example of what I would love to do:

import { Request, Response } from 'express'

interface AuthenticateParams {
    email: string
    password: string
}

type AuthenticationRequest = Request & {body: AuthenticateParams}

const authenticate = async (req: AuthenticationRequest, res: Response) => {
    if (typeof req.body !== AuthenticateParams) res.status(400).send('Invalid body')

    // DO STUFF
    let stuff

    res.status(200).send(stuff)
}

export default authenticate


Solution 1:[1]

Interfaces in typescript are purely a compile-time construct. What you are trying to do is dynamically check the type of the body.

You can achieve what you want with a schema validator.

Solution 2:[2]

There is no way to do that. Interfaces only exist when compiling and checking your code, but TypeScript has no runtime.

Once your TypeScript code is compiled, it becomes normal JavaScript. And JavaScript has no concept of interfaces, so it can't check that.

You basically need to write your own function to verify the interface by, for example, checking that specific fields exist on the object, or that it's an instance of a specific class.

Solution 3:[3]

Here is my best helper for checking property keys, while being integrated with typescript. There is a change that this could be extended recursively.

function hasKeys<T, K extends string | number | symbol>(
    obj: T, 
    keys: K | K[]
): obj is T & { [P in K]: unknown } {
    return Array.isArray(keys) ? keys.every(k => k in obj) : keys in obj;
}
declare const obj: unknown;

if(typeof obj === "object" && obj !== null) {
    if("prop" in obj) {
        // Property 'prop' does not exist on type 'object'.ts(2339)
        let x = obj.prop;
    }

    if(hasKeys(obj, "prop")) {
        let x = obj.prop;
    }

    if(hasKeys(obj, ["prop1", "prop2"])) {
        let x = obj.prop1;
        let y = obj.prop2;
    }
}

Solution 4:[4]

If you also maintaining openapi documentation, you can validate the request using express-openapi-validator. It is also available for fastify and Koa

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 tony
Solution 2 nialna2
Solution 3 Hunter Kohler
Solution 4 Vikas