Combining type inference validation and authentication middleware in Express routes can be a powerful way to enhance security and ensure

I am struggling to grasp how types are automatically determined in Express routes when utilizing multiple middlewares.

To conduct validation using zod, I have employed the middleware package express-zod-safe, although a similar issue arose with alternative middleware like zod-express-middleware.

One of my middlewares, auth, ideally should execute first to prevent unauthorized access. However, before implementing it, I need to perform validation to ensure accurate type inference:

import express from "express";
import validate from "express-zod-safe";
import { z } from "zod";

const app = express();

export function checkAuth<
  T extends express.Request,
  U extends express.Response,
  V extends express.NextFunction
>() {
  return (req: T, res: U, next: V) => {
    next();
  };
}

const schema = z.object({ id: z.coerce.number().min(0) });

app.get(
  "/api/product/:id",
  validate({ params: schema }), // This line should be after checkAuth
  checkAuth(),
  (req, res) => {
    req.params.test; // The Typescript server only rightfully complains when I validate first
    res.send("Here's a product");
  }
);

app.listen(3000, () => console.log("Server running on port 3000"));

Edit: As I plan to incorporate additional routes with varying params, I aim for the TypeScript server to automatically infer these types while keeping the checkAuth function completely generic.

Edit 2: Initially, I managed to prioritize checkAuth by assigning any to the request type, but this resulted in losing the Request typing within it. How can I merge both types seamlessly?

export function checkAuth() {
  return (req: any, res: any, next: any) => {
    const authorizationHeader = req.headers.authorization;
    next();
  };
}

Edit 3: Following some adjustments using never, I achieved correct typing for both functions:

export function checkAuth() {
  return (req: express.Request<never>, res: any, next: any) => {
    const authorizationHeader = req.headers.authorization;
    next();
  };
}

However, I remain unsure about the functioning behind this solution. It seems like postponing type inference to the subsequent function, while any neglects all further typing. Is this the expected behavior? Any recommended resources for understanding TypeScript typing better?

Answer №1

The function checkAuth allows you to define the types for req as shown below:

export function checkAuth<
  T extends express.Request,
  U extends express.Response,
  V extends express.NextFunction
>() {
  return (req: T & { params: { id: number } }, res: U, next: V) => {
    // With this setup, TypeScript recognizes the existence of the "id" property in params
    req.params.id;
    next();
  };
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The call to react.cloneElement does not match any overloads

I'm encountering a typescript error in my React code when using React.cloneElement with the first parameter "children", and I am unsure of how to resolve it. As a newcomer to typescript, I believe that the type definitions in index.d.ts for cloneElem ...

Restrictions on pairings of kind variables within generic utilization

Currently, I am creating a declaration file for a library called chart.js. The process of constructing a new chart involves the following: let chart = new Chart(ctx, { type: 'line', data: ..., options: ... }) The types of the data and options f ...

Enum-centric type guard

Could I create a custom type guard to verify if a specified string is part of a specific string enum in a more specialized way? Check out the following example: enum MyEnum { Option1 = 'option one', Option2 = 'option two', } const ...

Vuetify 3 does not display dialogs

I am attempting to integrate vuetify 3.alpha with vue 3. Below are the files I am working with: Temp.vue (obtained from vuetify example) <template> <div class="text-center"> <v-dialog v-model="dialog" w ...

typescript api overlooking the async await functionality

My controller contains an asynchronous method that is supposed to set a results object. However, I'm facing an issue where instead of waiting for the 'await' to finish executing, the code jumps to the response object call prematurely, leavin ...

Are the middleware functions in mongoose the same as the middleware functions in express?

I'm trying to understand the concept of middleware. Initially, I thought it referred to functions within the express framework. However, I now realize that middleware actually represents functions that intervene between asynchronous functions. It&apo ...

Encountering an ERR_CONNECTION_REFUSED error with node.js Express and HTTPS

nodejs version v6.11.5 After successfully hosting the website via Express and seeing it load, I encounter an ERR_CONNECTION_REFUSED error when trying to host it via https. Here is my code for hosting with https: var options = { ca: fs.readFileSync(__ ...

Updating particular form data using Express.js

Need help with an Express.js question. I have been working on creating a simple RPG charactersheet app to practice node, express, and web programming. I am stuck on how to refresh a single input textbox without clearing the rest of the form after rolling d ...

Struggling to integrate a JavaScript sdk with an Angular2 application due to missing dependencies

I've been struggling to incorporate the Magic: The Gathering SDK library into my Angular2 application. I've tried various methods, but nothing seems to work seamlessly. When I attempt to import the library using TypeScript like this: import { } ...

Loading game resources in advance for future or immediate utilization

I'm currently developing a game UI that involves a large number of image files, totaling around 30MB in size. I've been caching these images to the disk using service workers, but some of them are quite large at 3MB each. Even when they are retri ...

Setting a blank value or null equivalent to a field: Tips and tricks

Here is the component state that I am working with: interface Person { name: string; surname: string; } interface CompState{ //...fields ... person?: Person; } render() { if(this.state.person){ const comp = <div>{this. ...

The custom native date adapter is facing compatibility issues following the upgrade of Angular/Material from version 5 to 6

In my Angular 5 application, I had implemented a custom date adapter as follows: import {NativeDateAdapter} from "@angular/material"; import {Injectable} from "@angular/core"; @Injectable() export class CustomDateAdapter extends NativeDateAdapter { ...

Is there a way to specifically target the MUI paper component within the select style without relying on the SX props?

I have been experimenting with styling the Select MUI component using the styled function. I am looking to create a reusable style and move away from using sx. Despite trying various methods, I am struggling to identify the correct class in order to direct ...

What is the best way to retrieve specific information from a group of data using Mongoose?

I need assistance with extracting the number from a collection that contains only a name and a number. I also want to either change the number or store it in a variable. How can I achieve this? let dataSchema = new mongoose.Schema({ name: String ...

Difficulty in making a CORS POST request in EXPRESS & REACT while hosting on a specific domain

I have configured the express CORS module and am using react AXIOS on my host and domain. In my route middleware, I have defined CORS() which successfully works for GET requests. However, when it comes to POST and PUT requests, I encounter the Access-Cont ...

Leveraging the power of map in an Angular typescript file

I've been attempting to populate a Map in Angular by setting values dynamically. When certain buttons are clicked, the onClick function is invoked. typeArray: Map<number,string>; Rent(movieId: number){ this.typeArray.set(movieId,"Rental ...

If an error occurs at any point, I will need to sever the connection to Redis in my Node Express app

I have a series of middlewares with the first one connecting to redis router.get( '/wasup', middleware1, middleware2, middleware3 ) If an error occurs at any point, I need to disconnect from redis. Is there a simple way to implement this? Curre ...

What is the functionality of Express?

I've recently started learning about the MEAN stack and I discovered that it begins with the following: var http = require('http'), express = require('express'), app = express(); app.listen(8080); After typing node exampl ...

What could be causing the axios get and post requests to timeout after 5 button requests?

Trying to fetch and send data using axios in server (express, axios, react native) results in disconnection from the server after 5 button presses. Check out this web example for console logs Is there a preset timeout limit after 5 or 6 request calls? On ...

What is the process of integrating data retrieved from an SQL query into a Pug template using Express and MySQL?

Currently, I am in the process of developing a basic web application that will initially show a list of bus route numbers and names upon landing on the page. My tech stack includes MySQL integrated with Express and Pug. Below is the server-side code snippe ...