Currently I have a declaration file that looks like this:
import { AuthenticatedUser } from ".";
export interface AuthenticatedRequest {
isAuthenticated: boolean;
sid: string | null;
locals: {
user: AuthenticatedUser | null;
};
}
declare global {
namespace Express {
export interface Request extends AuthenticatedRequest {}
}
}
I assign these values in my middleware so I know the user will not be able to access certain routes when not authenticated. The problem is I have to do this in every route I have to use my user object:
if (!req.locals?.user) {
return res
.status(StatusCodes.UNAUTHORIZED)
.json({ message: ReasonPhrases.UNAUTHORIZED });
}
const { user } = req.locals;
How can I tell typescript that the user is authenticated for this route? Do I need to have a separate interface and import it into each of these files or is there a more elegant solution?
As always, thanks for your help.
Solved my problem by passing with a payload generic as the first argument and importing into each file (was already doing with regular request type).
import type { AuthenticatedUser } from ".";
import type { Request as ExpressRequest } from "express";
type AuthenticatedRequestPayload = { sid: string; user: AuthenticatedUser };
type UnauthenticatedRequestPayload = {
sid: string | null;
user: AuthenticatedUser | null;
};
type PayloadOption = "authenticated" | "unauthenticated";
export type TargetedRequest<Auth = PayloadOption> =
Auth extends "authenticated"
? AuthenticatedRequestPayload
: UnauthenticatedRequestPayload;
export type Request<
Auth = PayloadOption,
P = Record<string, unknown>,
ResBody = unknown,
ReqBody = unknown,
ReqQuery = Record<string, unknown>
> = ExpressRequest<P, ResBody, ReqBody, ReqQuery> & TargetedRequest<Auth>;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With