- Request and Response are both basic TS interfaces and express interfaces. You want to use the express one, so remember to import them correctly.
- NextFunction is the interface for next() and is also imported from ExpressJS.
- Async functions return Promises (which, in the TS language is
Promise<T>
whereT
is the type of data the Promise will return if fullfilled). In case of Express endpoints, you will useres.send()
, not return, soT
will bevoid
.
req.header("Authorization").replace("Bearer ", "") - error TS2532: Object is possibly 'undefined' when trying to get the authorization header
The solution to this error is actually very easy, but to understand it we need to think about data structure. The following explanation is a little bit more "technical" and dives into node_modules.
If we dig down into the typescript declarations of Express, we will discover that the request interface Express is an extesion of http.IncomingMessage
where headers have a type IncomingHttpHeaders
, coming from Node itself:
From /express/index.d.ts
(express type declarations)
interface Request<
P = core.ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = core.Query,
Locals extends Record<string, any> = Record<string, any>
> extends core.Request<P, ResBody, ReqBody, ReqQuery, Locals> {} //core.Request is the type we are going to explore next
From express-serve-static-core/index.d.ts
(npm package to handle express type, it comes with express by default)
export interface Request<
P = ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = ParsedQs,
Locals extends Record<string, any> = Record<string, any>
> extends http.IncomingMessage,
Express.Request {
get(name: 'set-cookie'): string[] | undefined;
get(name: string): string | undefined;
header(name: 'set-cookie'): string[] | undefined;
header(name: string): string | undefined; // <<<<<<<<<< LOOK HERE!
//there's more down here, but we don't care about it
What we see in the line I have marked, is that the Request interface has a "header" method that takes a string as parameter. This means that the line of code req.header("Authorization")
is not inherently wrong, but it still gives back an error. THe reason for the error is that the return type for the 1headermethod, is
string | undefined, which means that it could also return
undefined` if you passed no headers. TS does not know in advance if you are going to pass an Authorization header!
To solve this, we need to "assure" typescript that the return value will not be undefined, and we can do so by adding a !
operator, which will tell TS that this value will NEVER be undefined when this code runs.
req.header("Authorization").replace("Bearer ", "")
req.user - Property 'user' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>
- This is due to the fact that an express Request does not bear the user prop in its type declaration. You can solve this by extending the original Request class and adding the User to it, like this:
import { Request } from "express"
export interface RequestWithUser extends Request {
user: User //create the User interface according to your structure
}