You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fastify中JWT装饰器异步函数类型不匹配报错求助

修复Fastify JWT插件的TypeScript装饰器错误

问题描述

我正在使用Fastify框架,尝试添加两种JWT认证方式,使用的代码如下:

import fp from 'fastify-plugin';
import { FastifyInstance, FastifyRequest } from 'fastify';
import '@fastify/jwt';

declare module '@fastify/jwt' {
    interface FastifyJWT {
        payload: { id: number };
        user: {
            id: number;
            fullName: string;
            email: number;
            phoneNumber: number;
            role: string;
            blocked: false;
            userMethod: string;
            verified: boolean;
            createdAt: string;
        };
    }
}

const jwtPlugin = async (instance: FastifyInstance) => {
    instance.register(import('@fastify/jwt'), {
        secret: instance.configs.jwt.secret,
    });

    instance.decorate('authenticate', async (request: FastifyRequest) => {
        try {
            await request.jwtVerify();
        } catch (error) {
            throw instance.httpErrors.unauthorized();
        }
    });
    // check if user is authenticated without throwing error (used for check user location)
    instance.decorate('isAuthenticated', async (request: FastifyRequest) => {
        try {
            await request.jwtVerify();
        } catch (error) {
            return;
        }
    });
};

export default fp(jwtPlugin, {
    name: 'jwt-plugin',
});

但在instance.decorate的async (request: FastifyRequest) => {}异步函数处出现如下TypeScript错误:

No overload matches this call.
  Overload 1 of 4, '(property: string | symbol, value: null): FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>', gave the following error.
    Argument of type '(request: FastifyRequest) => Promise<void>' is not assignable to parameter of type 'null'.
  Overload 2 of 4, '(property: "isAuthenticated", value: GetterSetter<FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>, (this: FastifyInstance<...>) => void>, dependencies?: string[] | undefined): FastifyInstance<...>', gave the following error.
    Argument of type '(request: FastifyRequest) => Promise<void>' is not assignable to type 'GetterSetter<FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>, (this: FastifyInstance<...>) => void>'.
      Type '(request: FastifyRequest) => Promise<void>' is not assignable to type '(this: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>) => void'.
        Target signature provides too few arguments. Expected 1 or more, but got 0.ts(2769)

该代码是从之前参与的项目中复制的,当时可正常运行,请问该如何修复这个错误?

修复方案

错误原因

你误用了Fastify的装饰器方法:decorate是用来给Fastify实例本身添加属性/方法的,而你要实现的是给**请求对象(FastifyRequest)**添加认证方法,应该用decorateRequest。同时新版本Fastify的TypeScript类型定义更严格,需要显式扩展FastifyRequest的类型声明。

具体修复步骤

  1. 替换装饰器方法:把instance.decorate替换为instance.decorateRequest,因为这两个认证方法是要绑定到每个请求对象上的。
  2. 扩展FastifyRequest类型:添加类型声明,让TypeScript识别新增的请求方法。
  3. 修正字段类型错误:原代码中user接口的email和phoneNumber被定义为number,这不符合实际场景,应该改为string;blocked写死为false,改为boolean更合理。

修复后的完整代码

import fp from 'fastify-plugin';
import { FastifyInstance, FastifyRequest } from 'fastify';
import '@fastify/jwt';

declare module '@fastify/jwt' {
    interface FastifyJWT {
        payload: { id: number };
        user: {
            id: number;
            fullName: string;
            email: string; // 修正为string类型
            phoneNumber: string; // 修正为string类型
            role: string;
            blocked: boolean; // 改为boolean类型支持两种状态
            userMethod: string;
            verified: boolean;
            createdAt: string;
        };
    }
}

// 扩展FastifyRequest类型,声明新增的方法
declare module 'fastify' {
    interface FastifyRequest {
        authenticate: () => Promise<void>;
        isAuthenticated: () => Promise<void>;
    }
}

const jwtPlugin = async (instance: FastifyInstance) => {
    instance.register(import('@fastify/jwt'), {
        secret: instance.configs.jwt.secret,
    });

    // 使用decorateRequest给请求对象添加方法,用function确保this指向当前请求
    instance.decorateRequest('authenticate', async function (this: FastifyRequest) {
        try {
            await this.jwtVerify();
        } catch (error) {
            throw instance.httpErrors.unauthorized();
        }
    });

    // check if user is authenticated without throwing error (used for check user location)
    instance.decorateRequest('isAuthenticated', async function (this: FastifyRequest) {
        try {
            await this.jwtVerify();
        } catch (error) {
            return;
        }
    });
};

export default fp(jwtPlugin, {
    name: 'jwt-plugin',
});

额外说明

  • 使用普通函数而非箭头函数,确保this能正确指向当前请求对象,避免jwtVerify调用时的上下文问题。
  • 调整后的字段类型更贴合实际业务场景,避免后续使用时出现类型不匹配的问题。

内容的提问来源于stack exchange,提问作者user10596155

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 06:25:20