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

注册@fastify/middie插件时出现类型匹配错误求助

问题

将Fastify集成到自研小型包中,需通过@fastify/middie使用中间件,但注册middie插件时编辑器抛出类型匹配错误:

No overload matches this call.
Overload 1 of 3, '(plugin: FastifyPluginCallback<FastifyMiddieOptions, Server, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
Argument of type 'FastifyMiddie' is not assignable to parameter of type 'FastifyPluginCallback<FastifyMiddieOptions, Server, FastifyTypeProvider, FastifyBaseLogger>'.
Types of parameters 'instance' and 'instance' are incompatible.
Property 'use' is missing in type 'FastifyInstance<Server, IncomingMessage, ServerResponse, FastifyBaseLogger, FastifyTypeProvider>' but required in type 'FastifyInstance<Server, IncomingMessage, ServerResponse, FastifyLoggerInstance>'.
Overload 2 of 3, '(plugin: FastifyPluginAsync<FastifyMiddieOptions, Server, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
Argument of type 'FastifyMiddie' is not assignable to parameter of type 'FastifyPluginAsync<FastifyMiddieOptions, Server, FastifyTypeProvider, FastifyBaseLogger>'.
Overload 3 of 3, '(plugin: FastifyPluginCallback<FastifyMiddieOptions, Server, FastifyTypeProvider, FastifyBaseLogger> | FastifyPluginAsync<...> | Promise<...> | Promise<...>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
Argument of type 'FastifyMiddie' is not assignable to parameter of type 'FastifyPluginCallback<FastifyMiddieOptions, Server, FastifyTypeProvider, FastifyBaseLogger> | FastifyPluginAsync<...> | Promise<...> | Promise<...>'.
Type 'FastifyMiddie' is not assignable to type 'FastifyPluginCallback<FastifyMiddieOptions, Server, FastifyTypeProvider, FastifyBaseLogger>'.

错误提示@fastify/middie未实现use()方法,替换为@fastify/express插件仍出现相同错误,推测是插件注册方式有误。相关代码如下:

import Fastify, { FastifyInstance } from 'fastify';
import Cors from '@fastify/cors';
import Static from '@fastify/static';
import FastifyMiddie from '@fastify/middie';

/**
 * HttpServer
 * 
 * The Solidus HttpServer.
 */
export class HttpServer implements HttpServerInterface {

    private readonly _rootComponent: Component;
    private readonly _server: FastifyInstance;
    private readonly _middleware: Middleware[];
    private readonly _config: Configuration;
    private readonly _corsOptions?: CorsOptions

    constructor(
        root: Component,
        config: Configuration,
        middleware: Middleware[] = [],
        cors: CorsOptions|undefined = undefined
    ) {
        this._rootComponent = root;
        this._middleware = middleware;
        this._config = resolveConfig(config);
        this._corsOptions = cors;
        this._server = Fastify({
            logger: true
        });
        this._setupServer();
    }

    // other stuff here....

    /**
     * _setupServer()
     * 
     * _setupServer() sets up the HttpServer.
     */

    private _setupServer(): void {
        // register middleware if it is defined
        if (this._middleware.length > 0) {
             // register middleware.

            // this line is throwing the error.
            this._server.register(FastifyMiddie, {
                hook: 'preHandle'
            });
            this._middleware.forEach(middleware => this._server.use(middleware));
        }

        // set up cors if it is enabled.
        if (this._corsOptions) {
            this._server.register(Cors, {
                // cors settings.
                allowedHeaders: this._corsOptions?.allowHeaders,
                credentials: this._corsOptions.credentials,
                exposedHeaders: this._corsOptions.exposeHeaders,
                hideOptionsRoute: this._corsOptions.hideOptionsRoute,
                maxAge: this._corsOptions.maxAge,
                methods: this._corsOptions.methods,
                optionsSuccessStatus: this._corsOptions.optionsSuccessStatus,
                origin: this._corsOptions.origin,
                preflight: this._corsOptions.preflight,
                preflightContinue: this._corsOptions.preflightContinue,
                strictPreflight: this._corsOptions.strictPreflight
            });
        }

        // register public path.
        this._server.register(Static, {
            root: join(process.cwd(), '/dist/public'),
        });

        // register the error handler
        this._server.setErrorHandler((error, req, res) => {
            this._server.log.error(error.message);
            res.status(500).send('Server Error');
        });

        // register the main route.
        this._server.get('*', async (req, res) => {
            const tags: TagDescription[] = []
            const App = this._configureRootComponent(this._rootComponent, req.url, req.ip, tags);

            if (this._config.ssr! === 'stream') {
                renderToStream(() => <App />).pipe(res.raw);
            }
            else {
                let page: string;

                try {
                    if (this._config.ssr! === 'async') {
                        page = await renderToStringAsync(() => <App />);
                    }
                    else {
                        page = renderToString(() => <App />);
                    }
                    res
                        .status(200)
                        .header('Content-Type', 'text/html')
                        .send(this._configureResponse(page, tags));
                }
                catch (e) {
                    this._server.log.error((e as Error).message);
                    res.status(500).send("Server Error");
                }
            }
        });
    }
}
解决方案

1. 导入middie类型扩展,修正TypeScript类型识别

注册@fastify/middie后,Fastify实例会新增use方法,但默认的FastifyInstance类型不包含该方法。需要导入middie提供的类型扩展文件:

import Fastify, { FastifyInstance } from 'fastify';
// 新增该行,扩展FastifyInstance类型以包含use方法
import '@fastify/middie';
import Cors from '@fastify/cors';
import Static from '@fastify/static';
import FastifyMiddie from '@fastify/middie';

2. 处理插件注册的异步流程

Fastify的register是异步操作,同步调用后立即使用use方法会导致类型未及时更新,同时存在运行时风险。需修改代码保证异步流程正确:

constructor(
    root: Component,
    config: Configuration,
    middleware: Middleware[] = [],
    cors: CorsOptions|undefined = undefined
) {
    this._rootComponent = root;
    this._middleware = middleware;
    this._config = resolveConfig(config);
    this._corsOptions = cors;
    this._server = Fastify({
        logger: true
    });
    // 用立即执行异步函数处理构造函数中的异步逻辑
    (async () => {
        await this._setupServer();
    })();
}

// 将_setupServer改为异步方法
private async _setupServer(): Promise<void> {
    if (this._middleware.length > 0) {
         // 等待middie插件注册完成
         await this._server.register(FastifyMiddie, {
             hook: 'preHandle'
         });
         this._middleware.forEach(middleware => this._server.use(middleware));
    }

    // 其余插件注册也建议使用await,保证执行顺序和类型正确
    if (this._corsOptions) {
        await this._server.register(Cors, {
            allowedHeaders: this._corsOptions?.allowHeaders,
            credentials: this._corsOptions.credentials,
            exposedHeaders: this._corsOptions.exposeHeaders,
            hideOptionsRoute: this._corsOptions.hideOptionsRoute,
            maxAge: this._corsOptions.maxAge,
            methods: this._corsOptions.methods,
            optionsSuccessStatus: this._corsOptions.optionsSuccessStatus,
            origin: this._corsOptions.origin,
            preflight: this._corsOptions.preflight,
            preflightContinue: this._corsOptions.preflightContinue,
            strictPreflight: this._corsOptions.strictPreflight
        });
    }

    await this._server.register(Static, {
        root: join(process.cwd(), '/dist/public'),
    });

    // 错误处理和路由注册无需await,可保留原有逻辑
    this._server.setErrorHandler((error, req, res) => {
        this._server.log.error(error.message);
        res.status(500).send('Server Error');
    });

    this._server.get('*', async (req, res) => {
        const tags: TagDescription[] = []
        const App = this._configureRootComponent(this._rootComponent, req.url, req.ip, tags);

        if (this._config.ssr! === 'stream') {
            renderToStream(() => <App />).pipe(res.raw);
        }
        else {
            let page: string;

            try {
                if (this._config.ssr! === 'async') {
                    page = await renderToStringAsync(() => <App />);
                }
                else {
                    page = renderToString(() => <App />);
                }
                res
                    .status(200)
                    .header('Content-Type', 'text/html')
                    .send(this._configureResponse(page, tags));
            }
            catch (e) {
                this._server.log.error((e as Error).message);
                res.status(500).send("Server Error");
            }
        }
    });
}

3. 可选:直接创建支持middie的Fastify实例

另一种简化方式是在创建Fastify实例时直接启用middie,无需手动注册插件,TypeScript会自动识别use方法:

this._server = Fastify({
    logger: true,
    // 直接传入middie插件,实例创建时自动启用
    plugin: FastifyMiddie
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 05:45:37