4

I'm creating a middleware that adds a "name" property to NextRequest, this property will be used in other parts of the API

import { NextRequest, NextResponse } from 'next/server'

export function middleware(req: NextRequest) {
    req.name = 'Foo'

    NextResponse.next()
}

I get this error Property 'name' does not exist on type 'NextRequest'

An alternative would be to create an interface that extends NextRequest, but I would have to import all files that want to access the "name" property

import { NextRequest, NextResponse } from 'next/server'

interface CustomRequest extends NextRequest {
    name: string
}

export function middleware(req: CustomRequest) {
    req.name = 'Foo'

    NextResponse.next()
}

Is there any way to add this property into NextRequest global types?

ellandor
  • 79
  • 1
  • 1
  • 9
  • 1
    Make `CustomRequest` a global type. See [Global types in typescript](https://stackoverflow.com/questions/42984889/global-types-in-typescript). – juliomalves Nov 30 '21 at 19:48
  • 1
    @juliomalves I checked it again and it worked, thanks – ellandor Dec 01 '21 at 12:51
  • Hey, could you please post an answer and example code of how you got this to work? I am stuck. Also, are you modifying the req object in the [middleware.ts](https://nextjs.org/docs/advanced-features/middleware) file or a custom middleware file? – YulePale Nov 17 '22 at 07:23
  • @YulePale Sorry for the delay, I created an answer showing the step by step – ellandor Nov 22 '22 at 12:59

1 Answers1

2

Showing how I solved the problem based on the comment from juliomalves


Create a .d.ts file, you can use any name

// global.d.ts
import { NextRequest as OriginalNextRequest } from 'next/server'

declare global {
    declare interface NextRequest extends OriginalNextRequest {
        name: string
    }
}

It is necessary:

  • extends OriginalNextRequest to show all NextRequest types of next

  • Rename the NextRequest import, otherwise when extending the NextRequest the typescript will think that NextRequest is the interface you are creating and will only show the name in the autocomplete

To import the modified NextRequest

// tsconfig.json

"paths": {
    "*": ["*.d.ts"]
}

If the .d.ts file is in a folder

"paths": {
    "*": ["types/*.d.ts"]
}

Now the typescript doesn't show the error saying name doesn't exist in NextRequest

import { NextResponse } from 'next/server'

export function middleware(req: NextRequest) {
    req.name = 'Foo'

    NextResponse.next()
}

NOTE: Do not import NextRequest from next, otherwise the global type will be replaced by NextRequest from import

import { NextRequest, NextResponse } from 'next/server'

export function middleware(req: NextRequest) {
    req.name = 'Foo' // error

    NextResponse.next()
}

If you want to use NextRequest from next, rename the import

ellandor
  • 79
  • 1
  • 1
  • 9