-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
269 lines (131 loc) · 56.5 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>夕风色</title>
<link href="http://example.com/atom.xml" rel="self"/>
<link href="http://example.com/"/>
<updated>2022-08-30T03:48:29.898Z</updated>
<id>http://example.com/</id>
<author>
<name>夕风色</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>React Hook useMemo 与 useCallback</title>
<link href="http://example.com/2022/08/19/develop/react/React-Hook-useMemo-%E4%B8%8E-useCallbacke/"/>
<id>http://example.com/2022/08/19/develop/react/React-Hook-useMemo-%E4%B8%8E-useCallbacke/</id>
<published>2022-08-19T14:34:58.000Z</published>
<updated>2022-08-30T03:48:29.898Z</updated>
<content type="html"><![CDATA[<h4 id="为什么使用-useMemo-和-useCallback"><a href="#为什么使用-useMemo-和-useCallback" class="headerlink" title="为什么使用 useMemo 和 useCallback"></a>为什么使用 useMemo 和 useCallback</h4><p>防止不必要的 effect / re-render / 计算.</p><h5 id="使用-useCallback"><a href="#使用-useCallback" class="headerlink" title="使用 useCallback"></a>使用 useCallback</h5><p>官网文档 <a href="https://zh-hans.reactjs.org/docs/hooks-reference.html#usecallback">useCallback</a>;</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> memoizedCallback = <span class="title function_">useCallback</span>(</span><br><span class="line"> <span class="function">() =></span> {</span><br><span class="line"> <span class="title function_">doSomething</span>(a, b);</span><br><span class="line"> },</span><br><span class="line"> [a, b],</span><br><span class="line">);</span><br></pre></td></tr></table></figure><p>在 <code>a</code> 和 <code>b</code> 的变量值不变的情况下,<code>memoizedCallback</code> 的引用不变。即:<code>useCallback</code> 的第一个入参函数会被缓存,从而达到渲染性能优化的目的。</p><h5 id="使用-useMemo"><a href="#使用-useMemo" class="headerlink" title="使用 useMemo"></a>使用 useMemo</h5><p>官网文档 <a href="https://zh-hans.reactjs.org/docs/hooks-reference.html#usememo">useMemo</a>;</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> memoizedValue = <span class="title function_">useMemo</span>(<span class="function">() =></span> <span class="title function_">computeExpensiveValue</span>(a, b), [a, b]);</span><br></pre></td></tr></table></figure><p>在 <code>a</code> 和 <code>b</code> 的变量值不变的情况下,<code>memoizedValue</code> 的值不变。即:<code>useMemo</code> 函数的第一个入参函数不会被执行,从而达到节省计算量的目的。</p><h5 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h5><p><code> useCallback</code> 与 <code>useMemo</code> 一个缓存的是函数,一个缓存的是函数的返回值。<code>useCallback</code> 是来优化子组件的,防止子组件的重复渲染。<code>useMemo</code> 可以优化当前组件也可以优化子组件,优化当前组件主要是通过 <code>memoize</code> 来将一些复杂的计算逻辑进行缓存,虽然 <code>useCallback</code> 和 <code>useMemo</code> 都可缓存函数的引用或值,但是从更细的使用角度来说 <code>useCallback</code> 缓存函数的引用,<code>useMemo</code> 缓存计算数据的值。</p><blockquote><p>useCallback 是要配合子组件的 shouldComponentUpdate 或者 React.memo 一起来使用的,否则就是反向优化。</p></blockquote><p><code>useMemo/useCallback</code> 使用准则:</p><ol><li>大部分的 <code>useMemo</code> 和 <code>useCallback</code> 都应该移除,他们可能没有带来任何性能上的优化,反而增加了程序首次渲染的负担,并增加程序的复杂性。</li><li>使用 <code>useMemo</code> 和 <code>useCallback</code> 优化子组件 re-render 时,必须同时满足以下条件才有效。<ol><li>子组件已通过 React.memo 或 <code>useMemo</code> 被缓存</li><li>子组件所有的 prop 都被缓存</li></ol></li><li>不推荐默认给所有组件都使用缓存,大量组件初始化时被缓存,可能导致过多的内存消耗,并影响程序初始化渲染的速度。</li></ol><h6 id="来源参考"><a href="#来源参考" class="headerlink" title="来源参考"></a>来源参考</h6><ol><li><a href="https://juejin.cn/post/7122027852492439565">如何正确使用 useMemo 和 useCallback</a></li><li><a href="https://codesandbox.io/s/usecallback1-yu1sp?file=/src/App.js">useCallback</a></li><li><a href="https://juejin.cn/post/6844904101445124110">详解 React useCallback & useMemo</a></li></ol>]]></content>
<summary type="html"><h4 id="为什么使用-useMemo-和-useCallback"><a href="#为什么使用-useMemo-和-useCallback" class="headerlink" title="为什么使用 useMemo 和 useCallback"></a>为什么使用</summary>
<category term="React" scheme="http://example.com/tags/React/"/>
<category term="React Hook" scheme="http://example.com/tags/React-Hook/"/>
</entry>
<entry>
<title>Typescript 资料</title>
<link href="http://example.com/2022/08/17/develop/typescript/Typescript-%E8%B5%84%E6%96%99/"/>
<id>http://example.com/2022/08/17/develop/typescript/Typescript-%E8%B5%84%E6%96%99/</id>
<published>2022-08-17T13:27:53.000Z</published>
<updated>2022-08-29T06:53:44.251Z</updated>
<content type="html"><![CDATA[<p><a href="https://jkchao.github.io/typescript-book-chinese/#why">深入理解 Typescript</a>(中文)<br><a href="https://www.typescriptlang.org/docs/handbook/typescript-from-scratch.html">Typescript 官方文档</a>(英文)<br><a href="https://ts.yayujs.com/">Typescript 中文文档</a>(冴羽版)<br><a href="https://ts.xcatliu.com/introduction/index.html">Typescript 中文文档</a>(流浪小猫版)<br><a href="https://zhongsp.gitbooks.io/typescript-handbook/content/">Typescript 中文文档</a>(Handbook)</p><p><a href="https://github.com/type-challenges/type-challenges/blob/main/README.zh-CN.md">Type Challenges</a>(TypeScript 类型体操姿势合集)<br><a href="https://github.com/ascoders/weekly/tree/master/TS%20%E7%B1%BB%E5%9E%8B%E4%BD%93%E6%93%8D">weekly/TS 类型体操</a>(TS 类型体操精读)</p>]]></content>
<summary type="html"><p><a href="https://jkchao.github.io/typescript-book-chinese/#why">深入理解 Typescript</a>(中文)<br><a href="https://www.typescriptlang.org/docs/h</summary>
<category term="typescript" scheme="http://example.com/tags/typescript/"/>
<category term="文档" scheme="http://example.com/tags/%E6%96%87%E6%A1%A3/"/>
</entry>
<entry>
<title>opensslErrorStack: [ ‘error:03000086:digital envelope routines::initialization error’ ]</title>
<link href="http://example.com/2022/08/15/develop/opensslErrorStack-%E2%80%98error-03000086-digital-envelope-routines-initialization-error%E2%80%99/"/>
<id>http://example.com/2022/08/15/develop/opensslErrorStack-%E2%80%98error-03000086-digital-envelope-routines-initialization-error%E2%80%99/</id>
<published>2022-08-15T11:08:41.000Z</published>
<updated>2022-08-29T05:55:22.042Z</updated>
<content type="html"><![CDATA[<h3 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h3><p>使用 Jenkins 对前端进行部署时,报了一个错误。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Error: error:0308010C:digital envelope routines::unsupported</span><br><span class="line">opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],</span><br><span class="line">library: 'digital envelope routines',</span><br><span class="line">reason: 'unsupported',</span><br><span class="line">code: 'ERR_OSSL_EVP_UNSUPPORTED'</span><br></pre></td></tr></table></figure><h3 id="解决-amp-问题"><a href="#解决-amp-问题" class="headerlink" title="解决 & 问题"></a>解决 & 问题</h3><ol><li><p><a href="https://github.com/webpack/webpack/issues/14532#issuecomment-947525539">webpack官方仓库讨论区</a></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">在 package.js 项目启动中添加 --openssl-legacy-provider</span><br><span class="line"></span><br><span class="line">{</span><br><span class="line"> "scripts": {</span><br><span class="line"> "build": "export NODE_OPTIONS=--openssl-legacy-provider; gatsby build"</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>服务器端是否系统进行了升级,从而改变了SSL策略。<br><a href="https://stackoverflow.com/a/73064710/5719959">node: –openssl-legacy-provider is not allowed in NODE_OPTIONS</a></p></li></ol><h4 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h4><ol><li><a href="https://exerror.com/opensslerrorstack-error03000086digital-envelope-routinesinitialization-error/">[Solved] opensslErrorStack: [ ‘error:03000086:digital envelope routines::initialization error’ ]</a></li><li><a href="https://github.com/webpack/webpack/issues/14532">nodejs 17: digital envelope routines::unsupported #14532</a></li><li><a href="https://dtuto.com/questions/7200/opensslerrorstack">opensslErrorStack: [ ‘error:03000086:digital envelope routines::initialization error’ ]</a></li></ol><h3 id="流程"><a href="#流程" class="headerlink" title="流程"></a>流程</h3><p>1.对之前部署成功的提交单独创建新的分支,进行部署,依然不能成功,报错!<br>2.本地进行部署,能够打包(build)成功。<br>3.更改 <em>registry</em> 配置,恢复默认为NPM包管理下载,保证包完整性。</p>]]></content>
<summary type="html"><h3 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h3><p>使用 Jenkins 对前端进行部署时,报了一个错误。</p>
<figure class="highlight plaintext"><t</summary>
<category term="javascript" scheme="http://example.com/tags/javascript/"/>
<category term="部署" scheme="http://example.com/tags/%E9%83%A8%E7%BD%B2/"/>
<category term="Jenkins" scheme="http://example.com/tags/Jenkins/"/>
</entry>
<entry>
<title>Typescript Pick选取 Omit排除</title>
<link href="http://example.com/2022/08/14/develop/typescript/Typescript-pick%E9%80%89%E5%8F%96-omit%E6%8E%92%E9%99%A4/"/>
<id>http://example.com/2022/08/14/develop/typescript/Typescript-pick%E9%80%89%E5%8F%96-omit%E6%8E%92%E9%99%A4/</id>
<published>2022-08-14T15:14:37.000Z</published>
<updated>2022-08-15T15:23:41.349Z</updated>
<content type="html"><![CDATA[<h4 id="Pick(选取)"><a href="#Pick(选取)" class="headerlink" title="Pick(选取)"></a>Pick(选取)</h4><p>假设咱们有一张用户数据表,其类型如下:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">interface <span class="title class_">User</span> { </span><br><span class="line"> uid : number; <span class="comment">// 用户ID </span></span><br><span class="line"> username : string; <span class="comment">// 用户名 </span></span><br><span class="line"> password : string; <span class="comment">// 密码 </span></span><br><span class="line"> email : string; <span class="comment">// 邮箱 </span></span><br><span class="line"> residence : string; <span class="comment">// 居住地 </span></span><br><span class="line"> job : string; <span class="comment">// 职业 </span></span><br><span class="line"> sex : number; <span class="comment">// 性别 </span></span><br><span class="line"> birthday : string; <span class="comment">// 生日</span></span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>如果我们写了一个注册接口,我们只需要传输用户名,邮箱,密码给后端。</p><p>正常的操作,我们可以写一个新的类型,并且将属性类型和表属性类型关联,这样我们只需新增或者删除类型的时候需要维护操作。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">interface <span class="title class_">RegisterArgs</span> { </span><br><span class="line"> username : <span class="title class_">User</span>[<span class="string">'username'</span>]; </span><br><span class="line"> email : <span class="title class_">User</span>[<span class="string">'email'</span>]; </span><br><span class="line"> password : <span class="title class_">User</span>[<span class="string">'password'</span>];</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>使用Pick可以简化成</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">type <span class="title class_">RegisterArgs</span> = <span class="title class_">Pick</span><<span class="title class_">User</span>, <span class="string">'username'</span> | <span class="string">'email'</span> | <span class="string">'password'</span>></span><br></pre></td></tr></table></figure><p>我们接着将上面的例子代入下面的 Pick 的原型,会容易理解。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">type <span class="title class_">Pick</span><T, K <span class="keyword">extends</span> keyof T> = { [key <span class="keyword">in</span> k]: T[key]}</span><br></pre></td></tr></table></figure><h4 id="Omit(排除)"><a href="#Omit(排除)" class="headerlink" title="Omit(排除)"></a>Omit(排除)</h4><p>还有一个接口,我想更新个人信息,除了密码不能更改之外,我们都要,但是除了uid之外都是可以缺省的,只要没有传输我们就置空。</p><p>PS:一般更改密码需要更多的权限校验,我们的场景是更新基本信息。</p><p>按照正常发展,我们会写成这样。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 除了uid是必须的,其他都可以省略 </span></span><br><span class="line">interface <span class="title class_">UpdateUserArgs</span> { </span><br><span class="line"> uid : <span class="title class_">User</span>[<span class="string">'uid'</span>] </span><br><span class="line"> username? : <span class="title class_">User</span>[<span class="string">'username'</span>]; </span><br><span class="line"> email? : <span class="title class_">User</span>[<span class="string">'email'</span>]; </span><br><span class="line"> residence? : <span class="title class_">User</span>[<span class="string">'residence'</span>]; </span><br><span class="line"> job? : <span class="title class_">User</span>[<span class="string">'job'</span>]; </span><br><span class="line"> sex? : <span class="title class_">User</span>[<span class="string">'sex'</span>]; </span><br><span class="line"> birthday? : <span class="title class_">User</span>[<span class="string">'birthday'</span>]</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>又是一堆属性堆砌,现在我们可以使用 Omit 进行简化。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">type <span class="title class_">UpdateUserArgs</span> = <span class="title class_">Pick</span><<span class="title class_">User</span>, <span class="string">'uid'</span>> & <span class="title class_">Partial</span><<span class="title class_">Omit</span><<span class="title class_">User</span>, <span class="string">'uid'</span>>></span><br></pre></td></tr></table></figure><p>是不是简单多了,上面我们用 Pick 选择了 uid 保证是必须的。然后用 Omit 将 uid 排除掉 ,拿到剩下的属性,并用 Partial 将属性转为可省略。</p><p>我们看下 Omit 的原型,然后将上面的例子代入原型,就可以更好理解了。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">type <span class="title class_">Omit</span><T, K <span class="keyword">extends</span> keyof any> = <span class="title class_">Pick</span><T, <span class="title class_">Exclude</span><keyof T, K>>;</span><br></pre></td></tr></table></figure><p>总的来说,使用内置工具类型增加类型重复利用,让你的代码看起来就像文档一样,赏心悦目。</p><p>不过使用 Pick 还是 Omit , 那就要看使用场景对比哪个维护成本更低。通俗来说如果需要 Pick 一堆属性,还是用 Omit 好 ,如果需要排除一堆属性,那还是用 Pick 好。</p><h5 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h5><ol><li><a href="https://blog.csdn.net/super_ying123/article/details/124465822">CSDN</a></li><li><a href="https://zhuanlan.zhihu.com/p/522017893">知乎</a></li></ol>]]></content>
<summary type="html"><h4 id="Pick(选取)"><a href="#Pick(选取)" class="headerlink" title="Pick(选取)"></a>Pick(选取)</h4><p>假设咱们有一张用户数据表,其类型如下:</p>
<figure class="highlig</summary>
<category term="typescript" scheme="http://example.com/tags/typescript/"/>
</entry>
<entry>
<title>Typescript 联合类型与交叉类型的区别</title>
<link href="http://example.com/2022/08/13/develop/typescript/Typescript-%E8%81%94%E5%90%88%E7%B1%BB%E5%9E%8B%E4%B8%8E%E4%BA%A4%E5%8F%89%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%8C%BA%E5%88%AB/"/>
<id>http://example.com/2022/08/13/develop/typescript/Typescript-%E8%81%94%E5%90%88%E7%B1%BB%E5%9E%8B%E4%B8%8E%E4%BA%A4%E5%8F%89%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%8C%BA%E5%88%AB/</id>
<published>2022-08-13T10:48:06.000Z</published>
<updated>2022-08-15T11:34:20.492Z</updated>
<content type="html"><![CDATA[<h5 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h5><blockquote><p>我们可以把联合类型理解为“或”,交叉类型理解为“与”</p></blockquote><h5 id=""><a href="#" class="headerlink" title=""></a></h5><h3 id="联合类型"><a href="#联合类型" class="headerlink" title="联合类型"></a>联合类型</h3><h5 id="基础类型"><a href="#基础类型" class="headerlink" title="基础类型"></a>基础类型</h5><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">type <span class="title class_">ShapeA</span> = <span class="string">'圆形'</span> | <span class="string">'方形'</span></span><br><span class="line"></span><br><span class="line">type <span class="title class_">ShapeB</span> = <span class="string">'梯形'</span> | <span class="string">'菱形'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="attr">shape</span>: <span class="title class_">ShapeA</span> | <span class="title class_">ShapeB</span> = <span class="string">'梯形'</span> <span class="comment">// 全部皆可</span></span><br></pre></td></tr></table></figure><p>对于基础类型的联合类型可以简单的理解为并集,满足其中之一即可。</p><h5 id="接口类型"><a href="#接口类型" class="headerlink" title="接口类型"></a>接口类型</h5><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">interface <span class="title class_">Plus</span>{</span><br><span class="line"> <span class="attr">isVip</span>: boolean;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">interface <span class="title class_">Person</span>{</span><br><span class="line"> <span class="attr">name</span>:string;</span><br><span class="line"> <span class="attr">age</span>:number;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 这里属性成员只要满足Person和Plus之一就行 就如"或"</span></span><br><span class="line"><span class="keyword">let</span> <span class="attr">vip</span>: <span class="title class_">Person</span> | <span class="title class_">Plus</span> = {</span><br><span class="line"> <span class="attr">isVip</span>: <span class="literal">true</span>,</span><br><span class="line"> <span class="attr">name</span>: <span class="string">'Sol'</span>,</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>对与接口类型的联合类型我们就不能简单的理解为并集了,而是从属性成员出发,它们的组合必须需要符合联合的类型的其中之一,满足这个条件之后才是并集,可以在满足这个类型基础上使用其他类型的部分或全部属性,比如:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> <span class="attr">name</span>:string;</span><br><span class="line"> <span class="attr">age</span>:number;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>上面对象满足了Person类型,那么接着我们可以使用Plus的isVip属性或者其他属性,但如果我删除了name属性,那么两种类型都不符合就会报错</p><h3 id="交叉类型"><a href="#交叉类型" class="headerlink" title="交叉类型"></a>交叉类型</h3><h5 id="基础类型-1"><a href="#基础类型-1" class="headerlink" title="基础类型"></a>基础类型</h5><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">type <span class="title class_">ShapeA</span> = <span class="string">'圆形'</span> | <span class="string">'方形'</span></span><br><span class="line"></span><br><span class="line">type <span class="title class_">ShapeB</span> = <span class="string">'梯形'</span> | <span class="string">'菱形'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="attr">shape</span>:<span class="title class_">ShapeA</span> & <span class="variable constant_">T2</span> = <span class="string">'圆形'</span> <span class="comment">// 只能是其中一种</span></span><br></pre></td></tr></table></figure><p>与联合类型相对应的,基础类型的交叉类型是交集</p><h5 id="接口类型-1"><a href="#接口类型-1" class="headerlink" title="接口类型"></a>接口类型</h5><p>对与接口类型的联合类型我们就不能简单的理解为并集了,而是从属性成员出发,它们的组合必须需要符合联合的类型的其中之一,满足这个条件之后才是并集,可以在满足这个类型基础上使用其他类型的部分或全部属性,比如:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">interface <span class="title class_">Plus</span>{</span><br><span class="line"> <span class="attr">isVip</span>: boolean;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">interface <span class="title class_">Person</span>{</span><br><span class="line"> <span class="attr">name</span>:string;</span><br><span class="line"> <span class="attr">age</span>:number;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 这里属性成员需要同时满足Person和Plus 就如"与"</span></span><br><span class="line"><span class="keyword">let</span> <span class="attr">b</span>:<span class="title class_">Person</span> & <span class="title class_">Plus</span> = {</span><br><span class="line"> <span class="attr">age</span>: <span class="number">19</span>,</span><br><span class="line"> <span class="attr">name</span>: <span class="string">'Sol'</span>,</span><br><span class="line"> <span class="attr">isVip</span>: <span class="literal">true</span>,</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>接口的交叉类型,简而言之就是要我们使用所有属性,属性名相同但类型不同会导致交叉的结果对应的属性变成never</p><h3 id="联合类型和交叉类型用在入参上"><a href="#联合类型和交叉类型用在入参上" class="headerlink" title="联合类型和交叉类型用在入参上"></a>联合类型和交叉类型用在入参上</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">interface <span class="title class_">Plus</span>{</span><br><span class="line"> <span class="attr">isVip</span>: boolean;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">interface <span class="title class_">Person</span>{</span><br><span class="line"> <span class="attr">name</span>:string;</span><br><span class="line"> <span class="attr">age</span>:number;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="title function_">func</span> = (<span class="params">obj:Person | Plus</span>) => {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="property">name</span>) <span class="comment">// 访问不到会报错</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">const</span> <span class="title function_">func2</span> = (<span class="params">obj:Person & Plus</span>) => {</span><br><span class="line"> <span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="property">name</span>) <span class="comment">// 所有属性均可访问</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>另外重要的一点是,如果联合类型用在了方法的入参上,则会有一些问题,如果是联合类型,也就意味着我们传入的参数可以是多种类型中的一种,哪种类型是我们人决定的,方法定义的时候,编译器并不知道,但如果是公用属性,即所有类型中都有这个属性,那么就可以方法,因为显然这个属性必定会传入。</p><p>如果只能用公共属性的话那不是太奇怪了吗,我目前能想到的方法是使用的时候手动断言参数的类型。</p><h3 id="PartialByKeys"><a href="#PartialByKeys" class="headerlink" title="PartialByKeys"></a>PartialByKeys</h3><h5 id="功能:将一对象类型的部分key类型变成可选"><a href="#功能:将一对象类型的部分key类型变成可选" class="headerlink" title="功能:将一对象类型的部分key类型变成可选"></a>功能:将一对象类型的部分key类型变成可选</h5><p>1、将传入的key类型变成可选<br>2、pick出除了传入的这几个key之外的没有变成可选的key<br>3、将变成可选的和没有变成可选的交叉运算一起</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// PartialByKeys</span></span><br><span class="line"><span class="comment">//工具类型</span></span><br><span class="line">type <span class="title class_">PartialByKeys</span><T, U <span class="keyword">extends</span> keyof T> = {</span><br><span class="line"> [K <span class="keyword">in</span> U]?: T[K]</span><br><span class="line">} & <span class="title class_">Pick</span><T, <span class="title class_">Exclude</span><keyof T, U>>;</span><br><span class="line"></span><br><span class="line">type <span class="variable constant_">U1</span> = {</span><br><span class="line"> <span class="attr">name</span>: string;</span><br><span class="line"> <span class="attr">age</span>: number;</span><br><span class="line"> <span class="attr">choose</span>: boolean;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line">type <span class="variable constant_">U2</span> = <span class="title class_">PartialByKeys</span><<span class="variable constant_">U1</span>, <span class="string">'name'</span>>;<span class="comment">// {name?: string;age:number;choose: boolean};</span></span><br><span class="line"><span class="keyword">let</span> <span class="attr">user</span>: <span class="variable constant_">U2</span> = {</span><br><span class="line"> <span class="attr">age</span>: <span class="number">11</span>,</span><br><span class="line"> <span class="attr">choose</span>: <span class="literal">true</span></span><br><span class="line">};<span class="comment">//正确</span></span><br></pre></td></tr></table></figure><h3 id="泛型变量TKVE与显式、隐式指定"><a href="#泛型变量TKVE与显式、隐式指定" class="headerlink" title="泛型变量TKVE与显式、隐式指定"></a>泛型变量TKVE与显式、隐式指定</h3><p>范型变量:<br>T(type):表示类型<br>K(key):表示对象中键的类型<br>V(value):表示对象中值的类型<br>E(Element):表示元素类型<br>这些都是约定俗成的写法</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 显式指定泛型</span></span><br><span class="line"><span class="keyword">function</span> foo1<T, R>(<span class="attr">x</span>: T, <span class="attr">y</span>: R) { }</span><br><span class="line">foo1<string, number>(<span class="string">'111'</span>, <span class="number">2</span>); <span class="comment">// function foo1<string, number>(x: string, y: number): void</span></span><br><span class="line"><span class="comment">// 隐式指定泛型</span></span><br><span class="line"><span class="title function_">foo1</span>(<span class="number">22</span>, <span class="string">'111'</span>)<span class="comment">// function foo1<number, string>(x: number, y: string): void</span></span><br></pre></td></tr></table></figure><h5 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h5><ol><li><a href="https://blog.csdn.net/qq_23670719/article/details/120207122">原文参考</a></li><li><a href="https://blog.csdn.net/qq_48896417/article/details/125092669">扩展参考</a></li></ol>]]></content>
<summary type="html"><h5 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h5><blockquote>
<p>我们可以把联合类型理解为“或”,交叉类型理解为“与”</p>
</blockquote>
<h5 id=""><a</summary>
<category term="typescript" scheme="http://example.com/tags/typescript/"/>
</entry>
<entry>
<title>React 组件类型定义的区别:JSX.Element vs ReactNode vs ReactElement</title>
<link href="http://example.com/2022/08/10/develop/react/React-%E7%BB%84%E4%BB%B6%E7%B1%BB%E5%9E%8B%E5%AE%9A%E4%B9%89%E7%9A%84%E5%8C%BA%E5%88%AB%EF%BC%9AJSX-Element-vs-ReactNode-vs-ReactElement/"/>
<id>http://example.com/2022/08/10/develop/react/React-%E7%BB%84%E4%BB%B6%E7%B1%BB%E5%9E%8B%E5%AE%9A%E4%B9%89%E7%9A%84%E5%8C%BA%E5%88%AB%EF%BC%9AJSX-Element-vs-ReactNode-vs-ReactElement/</id>
<published>2022-08-10T10:26:21.000Z</published>
<updated>2022-08-15T05:48:02.620Z</updated>
<content type="html"><![CDATA[<h5 id="组件类型定义"><a href="#组件类型定义" class="headerlink" title="组件类型定义"></a>组件类型定义</h5><p>很多人可能在使用 TypeScript 编写 React 应用的时候会对三种不同的函数返回值类型产生困惑,不明白它们之间的区别以及应该什么时候使用哪一种类型才比较严谨。</p><p>ReactElement 是含有 props 和 type 属性的对象:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">type <span class="title class_">Key</span> = string | number</span><br><span class="line"></span><br><span class="line">interface <span class="title class_">ReactElement</span><P = any, T <span class="keyword">extends</span> string | <span class="title class_">JSXElementConstructor</span><any> = string | <span class="title class_">JSXElementConstructor</span><any>> {</span><br><span class="line"> <span class="attr">type</span>: T;</span><br><span class="line"> <span class="attr">props</span>: P;</span><br><span class="line"> <span class="attr">key</span>: <span class="title class_">Key</span> | <span class="literal">null</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>ReactNode 则是多种类型的集合:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">type <span class="title class_">ReactText</span> = string | number;</span><br><span class="line">type <span class="title class_">ReactChild</span> = <span class="title class_">ReactElement</span> | <span class="title class_">ReactText</span>;</span><br><span class="line"></span><br><span class="line">interface <span class="title class_">ReactNodeArray</span> <span class="keyword">extends</span> <span class="title class_">Array</span><<span class="title class_">ReactNode</span>> {}</span><br><span class="line">type <span class="title class_">ReactFragment</span> = {} | <span class="title class_">ReactNodeArray</span>;</span><br><span class="line"></span><br><span class="line">type <span class="title class_">ReactNode</span> = <span class="title class_">ReactChild</span> | <span class="title class_">ReactFragment</span> | <span class="title class_">ReactPortal</span> | boolean | <span class="literal">null</span> | <span class="literal">undefined</span>;</span><br></pre></td></tr></table></figure><p>类组件的 render 成员函数会返回 ReactNode 类型的值,而且 PropsWithChildren 类型中指定的 children 类型也是 ReactNode。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="title class_">Comp</span>: <span class="title class_">FunctionComponent</span> = <span class="function"><span class="params">props</span> =></span> <span class="language-xml"><span class="tag"><<span class="name">div</span>></span>{props.children}<span class="tag"></<span class="name">div</span>></span></span> </span><br><span class="line"><span class="comment">// children?: React.ReactNode</span></span><br><span class="line"></span><br><span class="line">type <span class="title class_">PropsWithChildren</span><P> = P & {</span><br><span class="line"> children?: <span class="title class_">ReactNode</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>虽然 React 的类型定义看起来写得很复杂,但它实际上等价于:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> <span class="title class_">ReactNode</span> = {} | <span class="literal">null</span> | <span class="literal">undefined</span>;</span><br></pre></td></tr></table></figure><p>由于 {} 是所有对象的原型,你可以把几乎任何类型赋值给 ReactNode,但绝大多数情况下应该对它进行更详细的类型声明。</p><p>JSX.Element 通过执行 React.createElement 或是转译 JSX 获得。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> jsx = <span class="language-xml"><span class="tag"><<span class="name">div</span>></span>hello<span class="tag"></<span class="name">div</span>></span></span></span><br><span class="line"><span class="keyword">const</span> ele = <span class="title class_">React</span>.<span class="title function_">createElement</span>(<span class="string">"div"</span>, <span class="literal">null</span>, <span class="string">"hello"</span>);</span><br><span class="line"><p> // <- ReactElement = JSX.Element</span><br><span class="line"> <Custom> // <- ReactElement = JSX.Element</span><br><span class="line"> {true && "test"} // <- ReactNode</span><br><span class="line"> </Custom></span><br><span class="line"></p></span><br></pre></td></tr></table></figure><p>JSX 是一个全局的命名空间,不同的库对 JSX 都可以有自己不同的实现,而 React 的实现方式就是让 JSX.Element 等价于 ReactElement,同时将它的泛型 props 和 type 都设为 any:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">declare <span class="variable language_">global</span> {</span><br><span class="line"> namespace <span class="variable constant_">JSX</span> {</span><br><span class="line"> interface <span class="title class_">Element</span> <span class="keyword">extends</span> <span class="title class_">React</span>.<span class="property">ReactElement</span><any, any> { }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h5 id="返回类型的不同"><a href="#返回类型的不同" class="headerlink" title="返回类型的不同"></a>返回类型的不同</h5><p>有的同学可能会注意到:类组件渲染方法的返回值类型和函数组件的是不一样的,这是因为目前版本的 TypeScript 类型定义并不能准确地限定 React 实际值的范围:</p><p>类组件类型定义:通过 render() 返回 ReactNode,比 React 的实际值范围更宽松<br>函数组件类型定义:返回 JSX.Element,也比 React 的实际值范围更宽松<br>实际上 React 类组件中的 render() 和函数组件的返回类型是一样的,而 TypeScript 只是出于历史原因和向后兼容需要,为不同种类的组件声明了不同的返回值类型。</p><p>根据 <a href="https://reactjs.org/docs/react-component.html#render">文档的规定</a> 我们可以为组件返回值给出准确的类型定义:</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> <span class="title class_">ComponentReturnType</span> = <span class="title class_">ReactElement</span> | <span class="title class_">Array</span><<span class="title class_">ComponentReturnType</span>> | <span class="built_in">string</span> | <span class="built_in">number</span> | <span class="built_in">boolean</span> | <span class="literal">null</span></span><br><span class="line"><span class="comment">// 注意: 不能传入 undefined</span></span><br></pre></td></tr></table></figure><p>参考资料: </p><ol><li><a href="https://stackoverflow.com/questions/58123398/when-to-use-jsx-element-vs-reactnode-vs-reactelement">英文原文</a></li><li><a href="https://zhuanlan.zhihu.com/p/353239684">中文原文</a></li></ol>]]></content>
<summary type="html"><h5 id="组件类型定义"><a href="#组件类型定义" class="headerlink" title="组件类型定义"></a>组件类型定义</h5><p>很多人可能在使用 TypeScript 编写 React 应用的时候会对三种不同的函数返回值类型产生困惑,不</summary>
<category term="typescript" scheme="http://example.com/tags/typescript/"/>
<category term="react" scheme="http://example.com/tags/react/"/>
</entry>
<entry>
<title>typescript TS2532 对象可能未定义</title>
<link href="http://example.com/2022/08/08/develop/typescript/TypeScript-TS2532-%E5%AF%B9%E8%B1%A1%E5%8F%AF%E8%83%BD%E6%9C%AA%E5%AE%9A%E4%B9%89/"/>
<id>http://example.com/2022/08/08/develop/typescript/TypeScript-TS2532-%E5%AF%B9%E8%B1%A1%E5%8F%AF%E8%83%BD%E6%9C%AA%E5%AE%9A%E4%B9%89/</id>
<published>2022-08-08T09:32:42.000Z</published>
<updated>2022-08-15T08:22:26.719Z</updated>
<content type="html"><![CDATA[<p>问题:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="attr">arrayTemp</span>: string[] = [];</span><br><span class="line"><span class="comment">// 此时 objectArrayValue 会报 TS2532 对象可能未定义 的错误。</span></span><br><span class="line">arrayTemp.<span class="title function_">push</span>(...arrayTemp, ...objectArrayValue[<span class="number">0</span>])</span><br></pre></td></tr></table></figure><p>解决方案</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="attr">arrayTemp</span>: string[] = [];</span><br><span class="line"><span class="keyword">const</span> objectArrVal = objectArrayValue.<span class="property">length</span> ? objectArrayValue[<span class="number">0</span>] : [];</span><br><span class="line">arrayTemp.<span class="title function_">push</span>(...arrayTemp, ...objectArrVal)</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>问题:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span</summary>
<category term="typescript" scheme="http://example.com/tags/typescript/"/>
<category term="typescript报错" scheme="http://example.com/tags/typescript%E6%8A%A5%E9%94%99/"/>
</entry>
<entry>
<title>不能将类型"Timeout"分配给类型"number"</title>
<link href="http://example.com/2022/08/08/develop/typescript/Typescript%20%E4%B8%8D%E8%83%BD%E5%B0%86%E7%B1%BB%E5%9E%8B%22Timeout%22%E5%88%86%E9%85%8D%E7%BB%99%E7%B1%BB%E5%9E%8B%22number%22/"/>
<id>http://example.com/2022/08/08/develop/typescript/Typescript%20%E4%B8%8D%E8%83%BD%E5%B0%86%E7%B1%BB%E5%9E%8B%22Timeout%22%E5%88%86%E9%85%8D%E7%BB%99%E7%B1%BB%E5%9E%8B%22number%22/</id>
<published>2022-08-08T02:27:55.000Z</published>
<updated>2022-08-15T08:22:20.688Z</updated>
<content type="html"><![CDATA[<p>今天在整理旧代码时碰到了一个TS报错,描述是 *不能将类型”Timeout”分配给类型”number”*,</p><h5 id="解决方案:"><a href="#解决方案:" class="headerlink" title="解决方案:"></a>解决方案:</h5><p>根据不同的运行平台,给与使用方法添加不同的<em>父级对象</em>。<br>如果是运行在服务器端Node.js,请使用:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="attr">timeout</span>: <span class="title class_">NodeJS</span>.<span class="property">Timeout</span>;</span><br><span class="line"><span class="variable language_">global</span>.<span class="built_in">clearTimeout</span>(timeout);</span><br><span class="line">timeout = <span class="variable language_">global</span>.<span class="built_in">setTimeout</span>(<span class="function">() =></span> {}, <span class="number">100</span>);</span><br></pre></td></tr></table></figure><p>如果是运行在浏览器端,请使用:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> <span class="attr">timeout</span>: number;</span><br><span class="line"><span class="variable language_">window</span>.<span class="built_in">clearTimeout</span>(timeout);</span><br><span class="line">timeout = <span class="variable language_">window</span>.<span class="built_in">setTimeout</span>(<span class="function">() =></span> {}, <span class="number">100</span>);</span><br></pre></td></tr></table></figure><p><a href="https://stackoverflow.com/questions/45802988/typescript-use-correct-version-of-settimeout-node-vs-window">参考链接</a> </p>]]></content>
<summary type="html"><p>今天在整理旧代码时碰到了一个TS报错,描述是 *不能将类型”Timeout”分配给类型”number”*,</p>
<h5 id="解决方案:"><a href="#解决方案:" class="headerlink" title="解决方案:"></a>解决方案:</h5></summary>
<category term="typescript" scheme="http://example.com/tags/typescript/"/>
<category term="typescript报错" scheme="http://example.com/tags/typescript%E6%8A%A5%E9%94%99/"/>
</entry>
<entry>
<title>2022年 技术&学习阅读清单</title>
<link href="http://example.com/2022/08/01/life/2022%E5%B9%B4-%E6%8A%80%E6%9C%AF-%E5%AD%A6%E4%B9%A0%E9%98%85%E8%AF%BB%E6%B8%85%E5%8D%95/"/>
<id>http://example.com/2022/08/01/life/2022%E5%B9%B4-%E6%8A%80%E6%9C%AF-%E5%AD%A6%E4%B9%A0%E9%98%85%E8%AF%BB%E6%B8%85%E5%8D%95/</id>
<published>2022-08-01T11:06:44.000Z</published>
<updated>2022-08-30T04:39:24.305Z</updated>
<content type="html"><![CDATA[<h3 id="技术"><a href="#技术" class="headerlink" title="技术"></a>技术</h3><h4 id="进行:"><a href="#进行:" class="headerlink" title="进行:"></a>进行:</h4><p><a href="https://www.bilibili.com/video/BV1ev41147DQ?p=2&vd_source=7cbefa77af3d0c53bc6a9683b58ecd90">React Hook+TypeScript『业务开发思路』</a><br><a href="https://www.bilibili.com/video/BV15Y4y1z7Fc?spm_id_from=333.337.search-card.all.click&vd_source=7cbefa77af3d0c53bc6a9683b58ecd90">React Hooks 精讲</a><br><a href="https://github.com/type-challenges/type-challenges/blob/main/README.zh-CN.md">Type Challenges</a><br><a href="https://github.com/ascoders/weekly/tree/master/TS%20%E7%B1%BB%E5%9E%8B%E4%BD%93%E6%93%8D">Type Challenges 精读</a> </p><h4 id="已阅:"><a href="#已阅:" class="headerlink" title="已阅:"></a>已阅:</h4><p><a href="https://jkchao.github.io/typescript-book-chinese/">《深入理解 TypeScript》</a><br><a href="https://www.bilibili.com/video/BV1wR4y1377K?p=1&vd_source=7cbefa77af3d0c53bc6a9683b58ecd90">《小满TypeScript基础教程全集》</a><br>TypeScript入门与实战 第三章 5.12 已弃 </p><h3 id="英文"><a href="#英文" class="headerlink" title="英文"></a>英文</h3><p>《孙志立口语课堂》</p>]]></content>
<summary type="html"><h3 id="技术"><a href="#技术" class="headerlink" title="技术"></a>技术</h3><h4 id="进行:"><a href="#进行:" class="headerlink" title="进行:"></a>进行:</h4><p</summary>
<category term="学习" scheme="http://example.com/tags/%E5%AD%A6%E4%B9%A0/"/>
<category term="清单" scheme="http://example.com/tags/%E6%B8%85%E5%8D%95/"/>
</entry>
<entry>
<title>开发&线上Node版本不一致导致线上部署警告问题</title>
<link href="http://example.com/2022/07/29/develop/%E5%BC%80%E5%8F%91-%E7%BA%BF%E4%B8%8ANode%E7%89%88%E6%9C%AC%E4%B8%8D%E4%B8%80%E8%87%B4%E5%AF%BC%E8%87%B4%E7%BA%BF%E4%B8%8A%E9%83%A8%E7%BD%B2%E8%AD%A6%E5%91%8A%E9%97%AE%E9%A2%98/"/>
<id>http://example.com/2022/07/29/develop/%E5%BC%80%E5%8F%91-%E7%BA%BF%E4%B8%8ANode%E7%89%88%E6%9C%AC%E4%B8%8D%E4%B8%80%E8%87%B4%E5%AF%BC%E8%87%B4%E7%BA%BF%E4%B8%8A%E9%83%A8%E7%BD%B2%E8%AD%A6%E5%91%8A%E9%97%AE%E9%A2%98/</id>
<published>2022-07-29T04:55:31.000Z</published>
<updated>2022-08-10T12:13:13.656Z</updated>
<content type="html"><![CDATA[<p>今天线上部署前端分支时有一个警告⚠️报错。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm WARN read-shrinkwrap This version of npm is compatible with lockfileVersion@1, but package-lock.json was generated <span class="keyword">for</span> lockfileVersion@2. I’ll try to <span class="keyword">do</span> my best with it!</span><br></pre></td></tr></table></figure><p>使用关键字进行搜索,发现是因为开发环境Node版本与线上环境(生产)Node版本不一致,开发环境Node版本高于线上环境(生产)Node版本,<br>报错中 <em>lockfileVersion@1</em> 是指 npm5以及npm6版本,而 <em>lockfileVersion@2</em> 是指npm7版本以上标识。</p><p>NPM官方文档:<a href="https://docs.npmjs.com/cli/v7/configuring-npm/package-lock-json#lockfileversion">package-lock-json#lockfileversion</a></p><p>##解决方案:<br>1.线上环境Node升级<br>2.开发Node版本降至线上环境node版本在重新生成一下package-lock.json</p><p>##不建议临时解决方案<br>1.删除 <em>node_modules</em> 以及 <em>package-lock.json</em> 并重新安装依赖</p><p>参考文章<br><a href="https://www.abrahamberg.com/blog/npm-package-json-lock-version-1-or-2/">npm-package-json-lock-version-1-or-2</a></p>]]></content>
<summary type="html"><p>今天线上部署前端分支时有一个警告⚠️报错。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td</summary>
<category term="javascript" scheme="http://example.com/categories/javascript/"/>
<category term="node" scheme="http://example.com/tags/node/"/>
<category term="javascript" scheme="http://example.com/tags/javascript/"/>
<category term="npm" scheme="http://example.com/tags/npm/"/>
</entry>
</feed>