Stan Loona
Stan Loona

Reputation: 705

How do I extend Request's interface in Fastify with TypeScript

I have this declaration file in the project's root called fastify.d.ts:

import { auth } from "firebase-admin";

declare module 'fastify' {
  interface FastifyRequest {
    user: auth.DecodedIdToken
  }
}

And I've been using to set a user to an incoming request such as:

export default async function mustBeLoggedIn(
  req: FastifyRequest,
  reply: FastifyReply
) {
  try {
    const token = req.headers.authorization?.replace("Bearer ", "") ?? "";

    const result = await auth.verifyIdToken(token);

    req.user = result;
  } catch (err) {
    reply.status(401).send({
      error: "You must be logged in to access this resource",
    });
  }
}

And I get the error: middlewares/mustBeLoggedIn.ts(13,9): error TS2339: Property 'user' does not exist on type 'FastifyRequest<RouteGenericInterface, Server, IncomingMessage>'.

Current tsconfig.json:

{
  "compilerOptions": {
    "target": "es6",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
  },
  "include": ["**/*.ts", "**/*.d.ts"],
  "exclude": ["node_modules"]
}

How can I fix this? Thanks!

Upvotes: 2

Views: 6236

Answers (4)

Th3Ward3n
Th3Ward3n

Reputation: 11

import { auth } from "firebase-admin";

declare module 'fastify' {
  export interface FastifyRequest {
    user: auth.DecodedIdToken
  }
}

You must export the modified interface thus merging the namespaced module definition for FastifyRequest.

EDIT:

To clarify this kind of merger should be done in a .d.ts file of a differing name to the module being modified. Given the way fastify handles init, you may also find the method shown fails. import 'fastify' should be included at the top of the file, as the above answers linked post covers in detail as to why.

import 'fastify';

declare module 'fastify' {
    interface FastifyRequest {
        user: typeHere;
    }
}

Upvotes: 1

athul raj
athul raj

Reputation: 196

You can extend your request like this

export interface RequestCustom extends FastifyRequest {
  user: any;
}

and use it inside your function

  export default async function mustBeLoggedIn(
  req: RequestCustom,
  reply: FastifyReply
) {}

Upvotes: 0

Thiago Saquette
Thiago Saquette

Reputation: 51

Try import FastifyRequest, like this:

import FastifyRequest from "fastify";
import { auth } from "firebase-admin";

declare module 'fastify' {
  interface FastifyRequest {
    user: auth.DecodedIdToken
  }
}

Upvotes: 5

Daniel
Daniel

Reputation: 8677

Add

  "ts-node": {  "files": true },

to root level of tsconfig.json.

https://stackoverflow.com/a/68488480/6398044

Upvotes: -1

Related Questions