Next.js严格TypeScript环境下RenderPageResult类型获取方法咨询
解决Next.js 9.1.4自定义Document中RenderPageResult类型获取问题
首先,你直接导入next/dist/next-server/lib/utils里的RenderPageResult的做法并不推荐,原因有两点:
- 这个路径属于Next.js的内部私有模块,官方没有对外暴露,意味着它的结构和命名在后续版本(甚至同小版本更新)中都可能发生变化,会导致你的代码出现不可预期的类型错误。
next-env.d.ts是Next.js自动生成的声明文件,手动添加的/// <reference />指令很可能会被Next.js的自动生成逻辑覆盖,所以你才会发现修改没有作用。
最优解决方案:用ReturnType推导返回类型
你完全不需要手动导入内部类型,利用TypeScript的ReturnType工具类型,可以直接从originalRenderPage函数推导出它的返回类型,完美适配严格模式下的类型检查要求:
import Document, { Html, Head, Main, NextScript } from 'next/document'; import { SheetsRegistry } from 'react-jss'; // 匹配你使用样式收集的场景 export default class MyDocument extends Document { static async getInitialProps(ctx) { const sheets = new SheetsRegistry(); const originalRenderPage = ctx.renderPage; // 用ReturnType自动推导originalRenderPage的返回类型 ctx.renderPage = (): ReturnType<typeof originalRenderPage> => originalRenderPage({ enhanceApp: (App) => (props) => sheets.collect(<App {...props} />), }); const initialProps = await Document.getInitialProps(ctx); return { ...initialProps, styles: ( <> {initialProps.styles} <style id="server-side-styles">{sheets.toString()}</style> </> ), }; } // ... 其他Document组件渲染代码 }
这种方式的好处是完全依赖Next.js公开的类型定义,不需要接触内部私有模块,同时完美满足no implicit any return type的严格检查要求,类型也会和Next.js版本自动保持一致。
备选方案:自定义兼容的类型(不推荐,仅作参考)
如果你出于某些原因一定要明确写出类型名称,可以参考Next.js 9.1.4内部RenderPageResult的定义,在你的文件中自行声明一个兼容的接口:
import type { ReactElement } from 'react'; interface RenderPageResult { html: string; head?: Array<string | ReactElement>; } // 之后就可以直接使用这个类型 ctx.renderPage = (): RenderPageResult | Promise<RenderPageResult> => { // ... 你的代码逻辑 };
不过这种方式需要你自己维护这个类型的兼容性,如果Next.js内部类型有变化,你需要手动更新,所以还是优先推荐第一种ReturnType的方案。
内容的提问来源于stack exchange,提问作者Dusan
相关产品推荐
相关产品推荐

