我也跟上 發表於 2021-4-21 16:08:00

TypeScript在React项目中的使用总结

<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">序言</span></h2>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">本文会侧重于TypeScript(以下简称TS)在项目中与React的结合使用情况,而非TS的基本概念。关于TS的类型查看可以使用在线TS工具👉TypeScript游乐场</p>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">React元素相关</span></h2>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">React元素相关的类型主要包括<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">ReactNode</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">ReactElement</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">JSX.Element</code>。</p>
<ul style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: disc" data-tool="mdnice编辑器">
<li><code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">ReactNode</code>。表示任意类型的React节点,这是个联合类型,包含情况众多;</li>
<li><code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">ReactElement</code>/<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">JSX</code>。从使用表现上来看,可以认为这两者是一致的,属于<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">ReactNode</code>的子集,表示“<strong style="font-weight: bold; color: rgba(0, 0, 0, 1)">原生的DOM组件</strong>”或“<strong style="font-weight: bold; color: rgba(0, 0, 0, 1)">自定义组件的执行结果</strong>”。</li>
</ul>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">使用示例如下:</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;MyComp:&nbsp;React.FC&lt;{&nbsp;<span class="hljs-attr" style="line-height: 26px">title</span>:&nbsp;string;&nbsp;}&gt;&nbsp;=&nbsp;<span class="hljs-function" style="line-height: 26px">(<span class="hljs-params" style="line-height: 26px">{title}</span>)&nbsp;=&gt;</span>&nbsp;<span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">h2</span>&gt;</span>{title}<span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;/<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">h2</span>&gt;</span></span>;<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;ReactNode</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;a:&nbsp;React.ReactNode&nbsp;=<br>&nbsp;&nbsp;<span class="hljs-literal" style="color: rgba(0, 128, 128, 1); line-height: 26px">null</span>&nbsp;||<br>&nbsp;&nbsp;<span class="hljs-literal" style="color: rgba(0, 128, 128, 1); line-height: 26px">undefined</span>&nbsp;||&nbsp;<span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">div</span>&gt;</span>hello<span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;/<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">div</span>&gt;</span></span>&nbsp;||&nbsp;<span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">MyComp</span>&nbsp;<span class="hljs-attr" style="color: rgba(0, 128, 128, 1); line-height: 26px">title</span>=<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"world"</span>&nbsp;/&gt;</span></span>&nbsp;||<br>&nbsp;&nbsp;<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"abc"</span>&nbsp;||<br>&nbsp;&nbsp;<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">123</span>&nbsp;||<br>&nbsp;&nbsp;<span class="hljs-literal" style="color: rgba(0, 128, 128, 1); line-height: 26px">true</span>;<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;ReactElement和JSX.Element</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;b:&nbsp;React.ReactElement&nbsp;=&nbsp;<span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">div</span>&gt;</span>hello&nbsp;world<span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;/<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">div</span>&gt;</span></span>&nbsp;||&nbsp;<span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">MyComp</span>&nbsp;<span class="hljs-attr" style="color: rgba(0, 128, 128, 1); line-height: 26px">title</span>=<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"good"</span>&nbsp;/&gt;</span></span>;<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;c:&nbsp;JSX.Element&nbsp;=&nbsp;<span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">MyComp</span>&nbsp;<span class="hljs-attr" style="color: rgba(0, 128, 128, 1); line-height: 26px">title</span>=<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"good"</span>&nbsp;/&gt;</span></span>&nbsp;||&nbsp;<span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">div</span>&gt;</span>hello&nbsp;world<span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;/<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">div</span>&gt;</span></span>;<br></code></pre>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">原生DOM相关</span></h2>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">原生的 DOM 相关的类型,主要有以下这么几个:<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">Element</code>、 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLElement</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLxxxElment</code>。</p>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">简单来说: <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">Element = HTMLElement + SVGElement</code>。</p>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器"><code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">SVGElement</code>一般开发比较少用到,而<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLElement</code>却非常常见,它的子类型包括<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLDivElement</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLInputElement</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLSpanElement</code>等等。</p>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">因此我们可以得知,其关系为:<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">Element</code> &gt; <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLElement</code> &gt; <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">HTMLxxxElement</code>,原则上是尽量写详细。</p>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">React合成事件相关</span></h2>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">在 React 中,原生事件被处理成了<strong style="font-weight: bold; color: rgba(0, 0, 0, 1)">React 事件</strong>,其内部是通过事件委托来优化内存,减少DOM事件绑定的。言归正传,React 事件的通用格式为<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">Event</code>,常见的有<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">MouseEvent</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">ChangeEvent</code>、<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">TouchEvent</code>,是一个泛型类型,泛型变量为触发该事件的 DOM 元素类型。</p>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">示例如下:</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;input输入框输入文字</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;handleInputChange&nbsp;=&nbsp;<span class="hljs-function" style="line-height: 26px">(<span class="hljs-params" style="line-height: 26px">evt:&nbsp;React.ChangeEvent&lt;HTMLInputElement&gt;</span>)&nbsp;=&gt;</span>&nbsp;{<br>&nbsp;&nbsp;<span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(evt);<br>};<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;button按钮点击</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;handleButtonClick&nbsp;=&nbsp;<span class="hljs-function" style="line-height: 26px">(<span class="hljs-params" style="line-height: 26px">evt:&nbsp;React.MouseEvent&lt;HTMLButtonElement&gt;</span>)&nbsp;=&gt;</span>&nbsp;{<br>&nbsp;&nbsp;<span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(evt);<br>};<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;移动端触摸div</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;handleDivTouch&nbsp;=&nbsp;<span class="hljs-function" style="line-height: 26px">(<span class="hljs-params" style="line-height: 26px">evt:&nbsp;React.TouchEvent&lt;HTMLDivElement&gt;</span>)&nbsp;=&gt;</span>&nbsp;{<br>&nbsp;&nbsp;<span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(evt);<br>};<br></code></pre>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">与hooks的结合</span></h2>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">在hooks中,并非全部钩子都与TS有强关联,比如<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">useEffect</code>就不依赖TS做类型定义,我们挑选比较常见的几个和TS强关联的钩子来看看。</p>
<h3 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 20px" data-tool="mdnice编辑器"><span class="content">useState</span></h3>
<ol style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: decimal" data-tool="mdnice编辑器">
<li>如果初始值能说明类型,就不用给 useState 指明泛型变量;</li>
</ol>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;❌这样写是不必要的,因为初始值0已经能说明count类型</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;&nbsp;=&nbsp;useState&lt;number&gt;(<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">0</span>);<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;✅这样写好点</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;&nbsp;=&nbsp;useState(<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">0</span>);<br></code></pre>
<ol style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: decimal" start="2" data-tool="mdnice编辑器">
<li>如果初始值是 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">null</code> 或 <code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">undefined</code>,那就要通过泛型手动传入你期望的类型,并在访问属性的时候通过可选链来规避语法错误。</li>
</ol>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px">interface&nbsp;IUser&nbsp;{<br>&nbsp;&nbsp;<span class="hljs-attr" style="line-height: 26px">name</span>:&nbsp;string;<br>&nbsp;&nbsp;age:&nbsp;number;<br>}<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;&nbsp;=&nbsp;React.useState&lt;IUser&nbsp;|&nbsp;<span class="hljs-literal" style="color: rgba(0, 128, 128, 1); line-height: 26px">null</span>&gt;(<span class="hljs-literal" style="color: rgba(0, 128, 128, 1); line-height: 26px">null</span>);<br><br><span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(user?.name);<br></code></pre>
<h3 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 20px" data-tool="mdnice编辑器"><span class="content">useRef</span></h3>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">这个 hook 比较特别,它通常有两种用途:</p>
<ol style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: decimal" data-tool="mdnice编辑器">
<li>用来连接 DOM,以获取到 DOM 元素;</li>
</ol>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;连接DOM,初始值赋值为null,不能是undefined,如要指明泛型变量需要具体到HTMLxxxElement</span><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;如果我们确定inputRef.current在调用时一定是有值的,可以使用非空断言,在null后添加!</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;inputRef&nbsp;=&nbsp;useRef&lt;HTMLInputElement&gt;(<span class="hljs-literal" style="color: rgba(0, 128, 128, 1); line-height: 26px">null</span>!);<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;handleClick&nbsp;=&nbsp;<span class="hljs-function" style="line-height: 26px"><span class="hljs-params" style="line-height: 26px">()</span>&nbsp;=&gt;</span>&nbsp;{<br>&nbsp;&nbsp;inputRef.current.focus();&nbsp;<span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;当然不用非空断言,用inputEl.current?.focus()可选链也是可以的</span><br>}<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">return</span>&nbsp;(<br>&nbsp;&nbsp;<span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">input</span>&nbsp;<span class="hljs-attr" style="color: rgba(0, 128, 128, 1); line-height: 26px">ref</span>=<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">{inputRef}</span>&nbsp;/&gt;</span></span><br>&nbsp;&nbsp;<span class="xml" style="line-height: 26px"><span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">button</span>&nbsp;<span class="hljs-attr" style="color: rgba(0, 128, 128, 1); line-height: 26px">onClick</span>=<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">{handleClick}</span>&gt;</span>点击<span class="hljs-tag" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">&lt;/<span class="hljs-name" style="color: rgba(0, 0, 128, 1); font-weight: normal; line-height: 26px">button</span>&gt;</span></span><br>)<br></code></pre>
<ol style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: decimal" start="2" data-tool="mdnice编辑器">
<li>用来存储变量,由于是存储在函数式组件的外部,比起 useState,它不会存在异步更新的问题,也不会存在由<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">capture-value</code>特性引发的过时变量的问题,但是要注意赋值后由于ref引用没变,不会引起重渲染。</li>
</ol>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;通过初始值来自动指明泛型变量类型</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;sum&nbsp;=&nbsp;useRef(<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">0</span>);<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;通过.current直接赋值</span><br>sum.current&nbsp;=&nbsp;<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">3</span>;<br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;不存在异步更新问题</span><br><span class="hljs-built_in" style="color: rgba(0, 134, 179, 1); line-height: 26px">console</span>.log(sum.current);&nbsp;<span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;3</span><br></code></pre>
<h3 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 20px" data-tool="mdnice编辑器"><span class="content">useSelector</span></h3>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">useSelector用于获取store中的状态,其第一个固定参数为函数,函数的入参即为store,而store的类型<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">RootState</code>需要在store中提前定义好,一种常见的定义如下:</p>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">在store.ts中:</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;store&nbsp;=&nbsp;createStore(rootReducer);<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">export</span>&nbsp;type&nbsp;RootState&nbsp;=&nbsp;ReturnType&lt;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">typeof</span>&nbsp;rootReducer&gt;;<br></code></pre>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">使用时:</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;{&nbsp;var1,&nbsp;var2&nbsp;}&nbsp;=&nbsp;useSelector(<span class="hljs-function" style="line-height: 26px">(<span class="hljs-params" style="line-height: 26px">store:&nbsp;RootState</span>)&nbsp;=&gt;</span>&nbsp;store.xxx);<br></code></pre>
<h3 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 20px" data-tool="mdnice编辑器"><span class="content">自定义 hook</span></h3>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">如果我们需要仿照 useState 的形式,返回一个数组出去,则需要在返回值的末尾使用<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">as const</code>,标记这个返回值是个常量,否则返回的值将被推断成联合类型。</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;useInfo&nbsp;=&nbsp;<span class="hljs-function" style="line-height: 26px"><span class="hljs-params" style="line-height: 26px">()</span>&nbsp;=&gt;</span>&nbsp;{<br>&nbsp;&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;&nbsp;=&nbsp;useState(<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">0</span>);<br><br>&nbsp;&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">return</span>&nbsp;&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">as</span>&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>;&nbsp;<span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;类型为一个元组,</span><br>};<br></code></pre>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">redux相关</span></h2>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">对于<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">action</code>的定义,我们可以使用官方暴露的<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">AnyAction</code>,放宽对于<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">action</code>内部键值对的限制,如下:</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">import</span>&nbsp;{&nbsp;AnyAction&nbsp;}&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">from</span>&nbsp;<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"redux"</span>;<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;DEF_STATE&nbsp;=&nbsp;{<br>&nbsp;&nbsp;<span class="hljs-attr" style="line-height: 26px">count</span>:&nbsp;<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">0</span>,<br>&nbsp;&nbsp;<span class="hljs-attr" style="line-height: 26px">type</span>:&nbsp;<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">'integer'</span><br>};<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;使用redux的AnyAction放宽限制</span><br><span class="hljs-function" style="line-height: 26px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">function</span>&nbsp;<span class="hljs-title" style="color: rgba(153, 0, 0, 1); font-weight: bold; line-height: 26px">countReducer</span>(<span class="hljs-params" style="line-height: 26px">state&nbsp;=&nbsp;DEF_STATE,&nbsp;action:&nbsp;AnyAction</span>)&nbsp;</span>{<br>&nbsp;&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">switch</span>&nbsp;(action.type)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">case</span>&nbsp;<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"INCREASE_COUNT"</span>:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">return</span>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...state,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-attr" style="line-height: 26px">count</span>:&nbsp;state.count&nbsp;+&nbsp;<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">1</span>,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">case</span>&nbsp;<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">"DECREASE_COUNT"</span>:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">return</span>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...state,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-attr" style="line-height: 26px">count</span>:&nbsp;state.count&nbsp;-&nbsp;<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">1</span>,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">default</span>:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">return</span>&nbsp;state;<br>&nbsp;&nbsp;}<br>}<br><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">export</span>&nbsp;<span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">default</span>&nbsp;countReducer;<br></code></pre>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">规约</span></h2>
<ol style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: decimal" data-tool="mdnice编辑器">
<li>子组件的入参命名为<code style="font-size: 14px; word-wrap: break-word; padding: 2px 4px; border-radius: 4px; margin: 0 2px; background-color: rgba(27, 31, 35, 0.05); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; word-break: break-all; color: rgba(239, 112, 96, 1)">[组件名]Props</code>,如:</li>
</ol>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;比如当前组件名为InfoCard</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">export</span>&nbsp;interface&nbsp;InfoCardProps&nbsp;{<br>&nbsp;&nbsp;<span class="hljs-attr" style="line-height: 26px">name</span>:&nbsp;string;<br>&nbsp;&nbsp;age:&nbsp;number;<br>}<br></code></pre>
<ol style="margin-top: 8px; margin-bottom: 8px; padding-left: 25px; color: rgba(0, 0, 0, 1); list-style-type: decimal" start="2" data-tool="mdnice编辑器">
<li>interface接口类型以大写开头;</li>
<li>为后端接口的出入参书写interface,同时使用利于编辑器提示的jsdoc风格做注释,如:</li>
</ol>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">export</span>&nbsp;interface&nbsp;GetUserInfoReqParams&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">/**&nbsp;名字&nbsp;*/</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-attr" style="line-height: 26px">name</span>:&nbsp;string;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">/**&nbsp;年龄&nbsp;*/</span><br>&nbsp;&nbsp;&nbsp;&nbsp;age:&nbsp;number;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">/**&nbsp;性别&nbsp;*/</span><br>&nbsp;&nbsp;&nbsp;&nbsp;gender:&nbsp;string;<br>}<br></code></pre>
<h2 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); border-bottom: 2px solid rgba(239, 112, 96, 1); font-size: 1.3em" data-tool="mdnice编辑器"><span class="content" style="display: inline-block; font-weight: bold; background: rgba(239, 112, 96, 1); color: rgba(255, 255, 255, 1); padding: 3px 10px 1px; border-top-right-radius: 3px; border-top-left-radius: 3px; margin-right: 3px">其他</span></h2>
<h3 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 20px" data-tool="mdnice编辑器"><span class="content">键名或键值不确定如何处理?</span></h3>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;表示键名不确定,键值限制为number类型</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">export</span>&nbsp;interface&nbsp;NotSureAboutKey&nbsp;{<br>&nbsp;&nbsp;:&nbsp;number;<br>}<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;当键名键值都不确定时,以下接口对任何对象都是适用的</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">export</span>&nbsp;interface&nbsp;AllNotSure&nbsp;{<br>&nbsp;&nbsp;:&nbsp;any;<br>}<br></code></pre>
<h3 style="margin-top: 30px; margin-bottom: 15px; padding: 0; font-weight: bold; color: rgba(0, 0, 0, 1); font-size: 20px" data-tool="mdnice编辑器"><span class="content">如何在接口中使用泛型变量?</span></h3>
<p style="font-size: 16px; padding-top: 8px; padding-bottom: 8px; margin: 0; line-height: 26px; color: rgba(0, 0, 0, 1)" data-tool="mdnice编辑器">所谓泛型,就是预定义类型。它的目的是:<strong style="font-weight: bold; color: rgba(0, 0, 0, 1)">达到类型定义的局部灵活,提高复用性</strong>。我们通常会在接口中使用泛型,如:</p>
<pre class="custom" data-tool="mdnice编辑器"><code class="hljs" style="overflow-x: auto; padding: 15px 16px 16px; color: rgba(51, 51, 51, 1); font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px; -webkit-overflow-scrolling: touch; background: rgba(248, 248, 248, 1); border-radius: 5px"><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;通常,我们会为接口的泛型变量指定一个默认类型</span><br>interface&nbsp;IHuman&lt;T&nbsp;=&nbsp;unknown&gt;&nbsp;{<br>&nbsp;&nbsp;<span class="hljs-attr" style="line-height: 26px">name</span>:&nbsp;string;<br>&nbsp;&nbsp;age:&nbsp;number;<br>&nbsp;&nbsp;gender:&nbsp;T;<br>}<br><br><span class="hljs-comment" style="color: rgba(153, 153, 136, 1); font-style: italic; line-height: 26px">//&nbsp;其他地方使用时</span><br><span class="hljs-keyword" style="color: rgba(51, 51, 51, 1); font-weight: bold; line-height: 26px">const</span>&nbsp;youngMan:&nbsp;IHuman&lt;string&gt;&nbsp;=&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-attr" style="line-height: 26px">name</span>:&nbsp;<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">'zhangsan'</span>,<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-attr" style="line-height: 26px">age</span>:&nbsp;<span class="hljs-number" style="color: rgba(0, 128, 128, 1); line-height: 26px">18</span>,<br>&nbsp;&nbsp;&nbsp;&nbsp;<span class="hljs-attr" style="line-height: 26px">gender</span>:&nbsp;<span class="hljs-string" style="color: rgba(221, 17, 68, 1); line-height: 26px">'male'</span><br>}<br></code></pre><br><br>
来源:https://www.cnblogs.com/zhangnan35/p/14685651.html
頁: [1]
查看完整版本: TypeScript在React项目中的使用总结