react(ts) 给第三方npm包react-page-lay
最近在写react/ts项目起手骨架,想省事一点,把之前的一个react项目起手骨架直接拿过来用。里面用到了一个公用布局第三方包react-page-layout,结果时间耽误好久在写这个包的d.ts声明文件,到最后还是被自己蠢哭了。写完之后,就记录一下。
首先install react-page-layout插件,安装完之后按照之前的布局代码将布局代码撸了一遍。(react-page-layout的具体使用方法请参考官方文档),撸好之后发现报错了。
![](https://img.haomeiwen.com/i4752248/be84470cc93930b1.jpeg)
按照提示 npm install @types/react-page-layout ,结果发现没有声明文件,估计插件作者已经忘了这插件了。理论上提pr是最好不过了。不过不是学习么,还是自己写下试试。
看了一遍ts声明文件的文档(https://www.tslang.cn/docs/handbook/declaration-files/introduction.html),还是先撸吧。
首先在src下面新建了@types目录,然后是react-page-layout目录,最后新建了index.d.ts文件,为什么这么建目录,为了看起来方便。比直接在根目录下建文件好看点。万一后面还有声明文件要写看起来也直观一点。(一般来说,ts 会解析项目中所有的 *.ts 文件。所以写好这个声明文件后,其他所有 *.ts 文件就都可以获得 react-page-layout的类型定义了。)
![](https://img.haomeiwen.com/i4752248/a7d002b72a386d07.jpeg)
既然是第三方的包,引入的时候使用import{...} from 'react-page-layout'的方式,那第一行就写 declare module 'react-page-layout' {} 这个了
![](https://img.haomeiwen.com/i4752248/8caa80d4e25bfacb.jpeg)
报错变了。好像有点效果啊,看看报错Module '"react-page-layout"' has no exported member 'Slot'. TS2305继续往下写吧。
![](https://img.haomeiwen.com/i4752248/94b4c4f4b0eaa0bf.jpeg)
报错又变了。继续往下撸吧。
![](https://img.haomeiwen.com/i4752248/2206ecca20ae21c0.jpeg)
神奇的报错。需要去看下插件里面关于Slot这个组件的代码了。
![](https://img.haomeiwen.com/i4752248/18a1a534be34766f.jpeg)
既然这样,先这么写吧。
![](https://img.haomeiwen.com/i4752248/bb7ed3d1b578d138.jpeg)
好像有点作用啊,因为报错又变了。
![](https://img.haomeiwen.com/i4752248/6dbd847f195313ca.jpeg)
刚刚的好像解决了。因为报错又变了。
![](https://img.haomeiwen.com/i4752248/f8e24fc24b7f7ee8.jpeg)
Slot部分的好像解决了
![](https://img.haomeiwen.com/i4752248/1b60c8f0b298ccc9.jpeg)
查看下插件关于LayoutProvider这部分代码
![](https://img.haomeiwen.com/i4752248/d1ddcd59d08ab3a5.jpeg)
于是继续按照上面的套路一直这么写下去。全部写完之后就是这样了
![](https://img.haomeiwen.com/i4752248/bf46512ceeee65a7.jpeg)
按照报错提示都撸完以后。。。怎么还报错。。。
![](https://img.haomeiwen.com/i4752248/063e2a562d4c965e.jpeg)
![](https://img.haomeiwen.com/i4752248/cd47fd3b2e08bd8e.jpeg)
在插件的build/page.js里面console了一下this.context,context下的getLayout方法是undefined,一时百思不得其解,困扰了好久。难道是声明文件写的不对造成context没传过来?中间把声明文件折腾出很多个版本,各种思路都有过(包括把的LayoutProvider里childContextTypes声明出来之类的),直到我感觉我要给作者提pr的时候,我看到了我的路由守卫文件。。。
![](https://img.haomeiwen.com/i4752248/99e4f1a6505e7e4d.jpeg)
我把LayoutProvider包在了Redirect外面。。。改成包裹在Route外面就好了。
![](https://img.haomeiwen.com/i4752248/0379e5869851b726.jpeg)
终于报错解决了,页面正常了。这个插件可以正常用了。
![](https://img.haomeiwen.com/i4752248/0895d870904e90da.jpeg)
又看到之前的注释里有写组件可能会添加自定义属性了,这个时候TS验证可能会报错,就又需要改声明文件了。
![](https://img.haomeiwen.com/i4752248/a7263232074bc520.jpeg)
干脆把声明文件改了。any大法真好
![](https://img.haomeiwen.com/i4752248/9c34edff697ccdf3.jpeg)
写这篇文章的时候,把之前的报错解决过程又重复了一遍。突然发现,原来只要export出来就直接可以用了,突然感觉自己是个十足的蠢货。。。
![](https://img.haomeiwen.com/i4752248/70f499a7b4293942.jpeg)
但是原因还是要分析的,个人感觉因为这是个react组件式的插件,依赖的react.d.ts,proptypes.d.ts都有声明,其实只要声明本身有这个定义就可以了。希望有大神帮忙解答下。