<table class="d-block"> <tbody class="d-block"> <tr class="d-block"> <td class="d-block comment-body markdown-body js-comment-body rgh-linkified-code">html
<p><code>unknown</code> 字面理解和 <code>any</code> 其实没差,任何类型均可赋值给它,但有一点,</p> <blockquote> <p>Anything is assignable to unknown, but unknown isn’t assignable to anything but itself and any without a type assertion or a control flow based narrowing</p> <p><em>--<a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html" rel="nofollow">TypeScript 3.0 Release notes - New unknown top type</a></em></p> </blockquote> <p><code>unknown</code> 类型不能赋值给除了 <code>unknown</code> 或 <code>any</code> 的其余任何类型,使用前必需显式进行指定类型,或是在有条件判断状况下可以隐式地进行类型推断的状况。</p> <p>下面代码是合法的:</p> <div class="highlight highlight-source-ts"><pre><span class="pl-k">let</span> a<span class="pl-k">:</span> <span class="pl-c1">unknown</span>; <span class="pl-k"><span class="pl-k">const</span></span> b<span class="pl-k">:</span> <span class="pl-c1">unknown</span> <span class="pl-k">=</span> <span class="pl-smi">a</span>; <span class="pl-k"><span class="pl-k">const</span></span> c<span class="pl-k">:</span> <span class="pl-c1">any</span> <span class="pl-k">=</span> <span class="pl-smi">a</span>;</pre></div> <p>由于 <code>unknown</code> 是能够赋值给 <code>unknown</code> 的,而下面的代码则不行,</p> <div class="highlight highlight-source-ts"><pre><span class="pl-k">let</span> a<span class="pl-k">:</span> <span class="pl-c1">unknown</span>; <span class="pl-c"><span class="pl-c">//</span> 🚨Type 'unknown' is not assignable to type 'number'.ts(2322)</span> <span class="pl-k"><span class="pl-k">const</span></span> b<span class="pl-k">:</span> <span class="pl-c1">number</span> <span class="pl-k">=</span> <span class="pl-smi">a</span>;</pre></div> <p>可是若是使用时,明确知道了类型,则能够这样来修正:</p> <div class="highlight highlight-source-ts"><pre><span class="pl-k">let</span> a<span class="pl-k">:</span> <span class="pl-c1">unknown</span>; <span class="pl-c"><span class="pl-c">//</span> 🚨Type 'unknown' is not assignable to type 'number'.ts(2322)</span> <span class="pl-k"><span class="pl-k">const</span></span> b<span class="pl-k">:</span> <span class="pl-c1">number</span> <span class="pl-k">=</span> <span class="pl-smi">a</span>;</pre></div> <p>或者在条件语句中,已经能够明确推断出类型:</p> <div class="highlight highlight-source-ts"><pre><span class="pl-k">let</span> a<span class="pl-k">:</span> <span class="pl-c1">unknown</span>; <span class="pl-k">let</span> b<span class="pl-k">:</span> <span class="pl-c1">number</span> <span class="pl-k">=</span> <<span class="pl-c1">number</span>><span class="pl-smi">a</span>;typescript
<span class="pl-k">function</span> isNumber(<span class="pl-v">val</span><span class="pl-k">:</span> <span class="pl-c1">any</span>)<span class="pl-k">:</span> <span class="pl-en">val</span> <span class="pl-k">is</span> <span class="pl-c1">number</span> { <span class="pl-k">return</span> <span class="pl-k">typeof</span> <span class="pl-smi">val</span> <span class="pl-k">===</span> <span class="pl-s"><span class="pl-pds">"</span>number<span class="pl-pds">"</span></span>; }安全
<span class="pl-k">if</span> (<span class="pl-en">isNumber</span>(<span class="pl-smi">a</span>)) { <span class="pl-smi">b</span> <span class="pl-k">=</span> <span class="pl-smi">a</span>; }</pre></div>markdown
<p>因此在使用时,<code>unknown</code> 类型会比 <code>any</code> 更加安全。这个安全体如今,虽然它和 <code>any</code> 同样存储了任意类型的值,可是具体使用的时候,这个类型须要显式肯定,由使用者进行指定将 <code>unknown</code> 转换成某一肯定类型。</p> <h2>优先级</h2> <h3>与正交类型的搭配</h3> <p>正交类型(intersection type)中,<code>unknown</code> 不起做用:</p> <div class="highlight highlight-source-ts"><pre><span class="pl-k">type</span> <span class="pl-en">T00</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">&</span> <span class="pl-c1">null</span>; <span class="pl-c"><span class="pl-c">//</span> null</span> <span class="pl-k">type</span> <span class="pl-en">T01</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">&</span> <span class="pl-c1">undefined</span>; <span class="pl-c"><span class="pl-c">//</span> undefined</span> <span class="pl-k">type</span> <span class="pl-en">T02</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">&</span> <span class="pl-c1">null</span> <span class="pl-k">&</span> <span class="pl-c1">undefined</span>; <span class="pl-c"><span class="pl-c">//</span> null & undefined (which becomes never)</span> <span class="pl-k">type</span> <span class="pl-en">T03</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">&</span> <span class="pl-c1">string</span>; <span class="pl-c"><span class="pl-c">//</span> string</span> <span class="pl-k">type</span> <span class="pl-en">T04</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">&</span> <span class="pl-c1">string</span>[]; <span class="pl-c"><span class="pl-c">//</span> string[]</span> <span class="pl-k">type</span> <span class="pl-en">T05</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">&</span> <span class="pl-c1">unknown</span>; <span class="pl-c"><span class="pl-c">//</span> unknown</span> <span class="pl-k">type</span> <span class="pl-en">T06</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">&</span> <span class="pl-c1">any</span>; <span class="pl-c"><span class="pl-c">//</span> any</span></pre></div> <h3>与联合类型的搭配</h3> <p>联合类型(union type)中 <code>unknown</code> 起绝对做用:</p> <div class="highlight highlight-source-ts"><pre><span class="pl-k">type</span> <span class="pl-en">T10</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">|</span> <span class="pl-c1">null</span>; <span class="pl-c"><span class="pl-c">//</span> unknown</span> <span class="pl-k">type</span> <span class="pl-en">T11</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">|</span> <span class="pl-c1">undefined</span>; <span class="pl-c"><span class="pl-c">//</span> unknown</span> <span class="pl-k">type</span> <span class="pl-en">T12</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">|</span> <span class="pl-c1">null</span> <span class="pl-k">|</span> <span class="pl-c1">undefined</span>; <span class="pl-c"><span class="pl-c">//</span> unknown</span> <span class="pl-k">type</span> <span class="pl-en">T13</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">|</span> <span class="pl-c1">string</span>; <span class="pl-c"><span class="pl-c">//</span> unknown</span> <span class="pl-k">type</span> <span class="pl-en">T14</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">|</span> <span class="pl-c1">string</span>[]; <span class="pl-c"><span class="pl-c">//</span> unknown</span> <span class="pl-k">type</span> <span class="pl-en">T15</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">|</span> <span class="pl-c1">unknown</span>; <span class="pl-c"><span class="pl-c">//</span> unknown</span> <span class="pl-k">type</span> <span class="pl-en">T16</span> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">|</span> <span class="pl-c1">any</span>; <span class="pl-c"><span class="pl-c">//</span> any</span></pre></div> <p>上面仅一个例外,及和 <code>any</code> 组成的联合类型,最终结果是 <code>any</code>。</p> <h3>使用在条件类型中</h3> <p>条件类型(conditional type)中,</p> <div class="highlight highlight-source-ts"><pre><span class="pl-k">type</span> <span class="pl-en">T30</span><<span class="pl-en">T</span>> <span class="pl-k">=</span> <span class="pl-c1">unknown</span> <span class="pl-k">extends</span> <span class="pl-en">T</span> <span class="pl-k">?</span> <span class="pl-c1">true</span> <span class="pl-k">:</span> <span class="pl-c1">false</span>; <span class="pl-c"><span class="pl-c">//</span> Deferred</span> <span class="pl-k">type</span> <span class="pl-en">T31</span><<span class="pl-en">T</span>> <span class="pl-k">=</span> <span class="pl-en">T</span> <span class="pl-k">extends</span> <span class="pl-c1">unknown</span> <span class="pl-k">?</span> <span class="pl-c1">true</span> <span class="pl-k">:</span> <span class="pl-c1">false</span>; <span class="pl-c"><span class="pl-c">//</span> Deferred (so it distributes)</span></pre></div> <p>对于上面的条件类型,进行如下测试:</p> <div class="highlight highlight-source-ts"><pre><span class="pl-c"><span class="pl-c">//</span> `unknown` 不能赋值给 `number`</span> <span class="pl-k">type</span> <span class="pl-en">foo</span> <span class="pl-k">=</span> <span class="pl-en">T30</span><<span class="pl-c1">number</span>>; <span class="pl-c"><span class="pl-c">//</span> false</span> <span class="pl-c"><span class="pl-c">//</span> `unknown` 能够赋值给 `any`</span> <span class="pl-k">type</span> <span class="pl-en">bar</span> <span class="pl-k">=</span> <span class="pl-en">T30</span><<span class="pl-c1">any</span>>; <span class="pl-c"><span class="pl-c">//</span> true</span>测试
<span class="pl-c"><span class="pl-c">//</span> 任何类型均可赋值给 unknown
,因此都为 true</span> <span class="pl-k">type</span> <span class="pl-en">a</span> <span class="pl-k">=</span> <span class="pl-en">T31</span><<span class="pl-c1">number</span>>; <span class="pl-c"><span class="pl-c">//</span> true</span> <span class="pl-k">type</span> <span class="pl-en">b</span> <span class="pl-k">=</span> <span class="pl-en">T31</span><<span class="pl-c1">any</span>>; <span class="pl-c"><span class="pl-c">//</span> true</span></pre></div>spa
<h2>可进行的操做</h2> <p>只能进行等于的判断,其余操做则会报错。</p> <div class="highlight highlight-source-ts"><pre><span class="pl-k">function</span> f10(<span class="pl-v">x</span><span class="pl-k">:</span> <span class="pl-c1">unknown</span>) { <span class="pl-smi">x</span> <span class="pl-k">==</span> <span class="pl-c1">5</span>; <span class="pl-smi">x</span> <span class="pl-k">!==</span> <span class="pl-c1">10</span>; <span class="pl-smi">x</span> <span class="pl-k">>=</span> <span class="pl-c1">0</span>; <span class="pl-c"><span class="pl-c">//</span> Error</span> <span class="pl-smi">x</span> <span class="pl-k">+</span> <span class="pl-c1">1</span>; <span class="pl-c"><span class="pl-c">//</span> Error</span> <span class="pl-smi">x</span> <span class="pl-k">*</span> <span class="pl-c1">2</span>; <span class="pl-c"><span class="pl-c">//</span> Error</span> <span class="pl-k">-</span><span class="pl-smi">x</span>; <span class="pl-c"><span class="pl-c">//</span> Error</span> <span class="pl-k">+</span><span class="pl-smi">x</span>; <span class="pl-c"><span class="pl-c">//</span> Error</span> }</pre></div> <p>属性字段获取,方法调用等,也是不容许的:</p> <div class="highlight highlight-source-ts"><pre><span class="pl-k">function</span> f11(<span class="pl-v">x</span><span class="pl-k">:</span> <span class="pl-c1">unknown</span>) { <span class="pl-smi">x</span>.<span class="pl-smi">foo</span>; <span class="pl-c"><span class="pl-c">//</span> Error</span> <span class="pl-smi">x</span>[<span class="pl-c1">5</span>]; <span class="pl-c"><span class="pl-c">//</span> Error</span> <span class="pl-en">x</span>(); <span class="pl-c"><span class="pl-c">//</span> Error</span> <span class="pl-k">new</span> <span class="pl-en">x</span>(); <span class="pl-c"><span class="pl-c">//</span> Error</span> }</pre></div> <p>当解构中有 <code>unknown</code> 类型时,会致使解构出来的结果也是 <code>unknown</code>。</p> <div class="highlight highlight-source-ts"><pre><span class="pl-k">function</span> f26(<span class="pl-v">x</span><span class="pl-k">:</span> {}, <span class="pl-v">y</span><span class="pl-k">:</span> <span class="pl-c1">unknown</span>, <span class="pl-v">z</span><span class="pl-k">:</span> <span class="pl-c1">any</span>) { <span class="pl-k">let</span> o1 <span class="pl-k">=</span> { a: <span class="pl-c1">42</span>, <span class="pl-k">...</span><span class="pl-smi">x</span> }; <span class="pl-c"><span class="pl-c">//</span> { a: number }</span> <span class="pl-k">let</span> o2 <span class="pl-k">=</span> { a: <span class="pl-c1">42</span>, <span class="pl-k">...</span><span class="pl-smi">x</span>, <span class="pl-k">...</span><span class="pl-smi">y</span> }; <span class="pl-c"><span class="pl-c">//</span> unknown</span> <span class="pl-k">let</span> o3 <span class="pl-k">=</span> { a: <span class="pl-c1">42</span>, <span class="pl-k">...</span><span class="pl-smi">x</span>, <span class="pl-k">...</span><span class="pl-smi">y</span>, <span class="pl-k">...</span><span class="pl-smi">z</span> }; <span class="pl-c"><span class="pl-c">//</span> any</span> }</pre></div> <h2>具体使用场景</h2> <p><code>unknown</code> 用于变量类型不肯定,但确定能够肯定的情形下,好比下面这个示例中,入参总归会有个值,根据这个值的类型进行不一样的处理,这里使用 <code>unknown</code> 替代 <code>any</code> 则会更加类型安全。</p> <div class="highlight highlight-source-ts"><pre><span class="pl-k">function</span> prettyPrint(<span class="pl-v">x</span><span class="pl-k">:</span> <span class="pl-c1">unknown</span>)<span class="pl-k">:</span> <span class="pl-c1">string</span> { <span class="pl-k">if</span> (<span class="pl-c1">Array</span>.<span class="pl-en">isArray</span>(<span class="pl-smi">x</span>)) { <span class="pl-k">return</span> <span class="pl-s"><span class="pl-pds">"</span>[<span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-smi">x</span>.<span class="pl-en">map</span>(<span class="pl-smi">prettyPrint</span>).<span class="pl-c1">join</span>(<span class="pl-s"><span class="pl-pds">"</span>, <span class="pl-pds">"</span></span>) <span class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">"</span>]<span class="pl-pds">"</span></span> } <span class="pl-k">if</span> (<span class="pl-k">typeof</span> <span class="pl-smi">x</span> <span class="pl-k">===</span> <span class="pl-s"><span class="pl-pds">"</span>string<span class="pl-pds">"</span></span>) { <span class="pl-k">return</span> <span class="pl-s"><span class="pl-pds">`</span>"${<span class="pl-smi">x</span>}"<span class="pl-pds">`</span></span> } <span class="pl-k">if</span> (<span class="pl-k">typeof</span> <span class="pl-smi">x</span> <span class="pl-k">===</span> <span class="pl-s"><span class="pl-pds">"</span>number<span class="pl-pds">"</span></span>) { <span class="pl-k">return</span> <span class="pl-c1">String</span>(<span class="pl-smi">x</span>) } <span class="pl-k">return</span> <span class="pl-s"><span class="pl-pds">"</span>etc.<span class="pl-pds">"</span></span> }</pre></div> <h2>相关资源</h2> <ul> <li><a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html" rel="nofollow">TypeScript 3.0 Release notes - New unknown top type</a></li> <li><a href="https://blog.logrocket.com/when-to-use-never-and-unknown-in-typescript-5e4d6c5799ad/" rel="nofollow">When to use <code>never</code> and <code>unknown</code> in TypeScript</a></li> </ul> </td> </tr> </tbody> </table>code