如何使用打字稿客户端读取预提取的服务器端数据?

时间:2019-05-30 19:53:20

标签: reactjs typescript window global

在缺乏JavaScript支持的情况下,我正在使用以下函数返回服务器渲染的初始标记和数据:

    export const serverRender = async () => {
        const { port, host } = config;
        const resp = await 
    axios.get(`http://${host}:${port}/testData.json`);

        const initialData = resp.data;
        return {
            initialMarkup: ReactDOMServer.renderToString(<App initialData={initialData} />),
            initialData,
        };
    };

我将这些数据提供给模板如下(细节并不那么重要):

    app.setViewEngine("pug");
    app.use(express.static(path.join(__dirname, "../public")));
    app.use(express.static(path.join(__dirname, "../assets")));
    app.enableCors();
    await app.listen(PORT, () => {
        console.log(`Nest App listening on port ${PORT}`);
    });

在我的模板中,我使用pug插值将initialData读入javascript(window)中的window.initialData = #{initialData}对象中。如果我的客户是JavaScript客户,则可以从window对象中读取内容,例如:window.initialData,但是Typescript不允许这样做。

我的问题是,传递预取数据并将其传递给客户端的最佳方法是什么?就是因此我在渲染客户端时可以执行以下操作:

    /* somehow grab pre-fetched data */
    ReactDOM.hydrate(<App />, document.getElementById("root")); // entry point for webpack

我并不是说这是最好的方法(这也是我问这个问题的另一个原因),但是在过去,对于小型的纯JavaScript项目,我已经如上所述将数据分配给window然后在react的客户端渲染中,我做了类似的事情:

    const initialData = window.initialData;
    ReactDOM.hydrate(<App initialData={initialData} />, document.getElementById("root")); // entry point for webpack

这在Typescript中不起作用

不适用

window情况下的错误消息: Property 'initialData' does not exist on type 'Window'

但是我还是想找到其他方法。

1 个答案:

答案 0 :(得分:2)

使用自定义的initialData值声明窗口全局对象的外观:

declare global {
    interface Window { initialData: any; }
}

一旦您声明了这一点,那么:

const initialData = window.initialData;

应该工作。