米晓秋 發表於 2019-11-7 02:53:00

TypeScript入门三:TypeScript函数类型

<ul style="color: rgba(41, 78, 128, 1)">
<li>TypeScript函数类型</li>
<li>TypeScript函数的参数</li>
<li>TypeScript函数的this与箭头函数</li>
<li>TypeScript函数重载</li>
</ul>
<h2 style="background-color: rgba(41, 78, 128, 1); border-radius: 5px">&nbsp;一、TypeScript函数类型</h2>
<p>&nbsp;在上一篇博客中已经对声明TypeScript类型变量已经做了初步的解析,这里先回顾以下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">声明函数</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> add1(x:number,y:number):number{
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> x+<span style="color: rgba(0, 0, 0, 1)">y;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> let add2 = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(x:number,y:number):number{
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> x +<span style="color: rgba(0, 0, 0, 1)"> y;
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">定义函数类型</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> type myAdd = (baseValue: number, increment: number) =&gt;<span style="color: rgba(0, 0, 0, 1)"> number;
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">根据函数类型声明函数变量</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> let myAdd1:myAdd = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(x:number,y:number) : number{
</span><span style="color: rgba(0, 128, 128, 1)">14</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> x +<span style="color: rgba(0, 0, 0, 1)"> y;
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">16</span> let myAdd2:myAdd = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(x:number,y:number) : number{
</span><span style="color: rgba(0, 128, 128, 1)">17</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> x -<span style="color: rgba(0, 0, 0, 1)"> y;
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">19</span>
<span style="color: rgba(0, 128, 128, 1)">20</span> let hintStamp(str:string):<span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">console.log(str);
</span><span style="color: rgba(0, 128, 128, 1)">22</span> }</pre>
</div>
<p>关于函数类型有一点需要注意,需要使用type关键字并使用等号"="赋值类型;如果使用let声明并使用冒号冒“:”表示的是声明一个函数变量,并且这个函数变量有指定的类型,这个变量不能作为函数类型,只能给它自己赋值指定类型的函数。</p>
<h2 style="background-color: rgba(41, 78, 128, 1); border-radius: 5px">&nbsp;二、TypeScript函数的参数</h2>
<p><span style="color: rgba(0, 0, 255, 1)">2.1 根据函数类型声明的函数变量,函数的实际参数名称可以不与函数类型的参数名称一致,这一点与对象类型Object的字段有点区别;</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> type myAdd = (baseValue: number, increment: number) =&gt;<span style="color: rgba(0, 0, 0, 1)"> number;
</span><span style="color: rgba(0, 128, 128, 1)">2</span> let myAdd1:myAdd = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(a:number,b:number) : number{
</span><span style="color: rgba(0, 128, 128, 1)">3</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> a +<span style="color: rgba(0, 0, 0, 1)"> b;
</span><span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">5</span> let myAdd2:myAdd = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(x:number,y:number) : number{
</span><span style="color: rgba(0, 128, 128, 1)">6</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> x -<span style="color: rgba(0, 0, 0, 1)"> y;
</span><span style="color: rgba(0, 128, 128, 1)">7</span> }</pre>
</div>
<p><span style="color: rgba(0, 0, 255, 1)">2.2 可选参数与默认参数:</span></p>
<p>这部非内容在官方文档中有详细的说明,这里简要的解析以下,如果有不明白的建议查看官方文档。</p>
<p>可选参数意思就是函数的参数在实际调用函数时,可以不需要全部对应传入,但是在定义函数类型时,必须设定默认参数。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">示例:在定义函数类型时,给参数b设定了默认参数:'TypeScript'</span>
<span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 255, 1)">function</span> foo (a: string,b = 'TypeScript'): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">3</span>   console.log(a + ':' +<span style="color: rgba(0, 0, 0, 1)"> b);
</span><span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">5</span> foo('hello');<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">hello:TypeScript</span></pre>
</div>
<p>设置了默认参数,就不需要设置参数的类型了,TypeScript的IDE会主动为我们推断出参数的类型,也就是默认值的类型,如果给可选参数传值就必须对应默认参数的类型。</p>
<p>除了设置既定的默认参数以外,还可以使用(参数名+?)的方式设置非特定参数,但是设置默认非特定参数需要设置默认参数的类型(参数名?:类型)。这种不设定特定值的可选参数,调用函数时不给这个可选参数传值的话就会默认为undefined。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">这是官方文档中的一个示例:</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 255, 1)">function</span> buildName(firstName: string, lastName?<span style="color: rgba(0, 0, 0, 1)">: string) {
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span>   <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (lastName){
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>   
<span style="color: rgba(0, 128, 128, 1)"> 5</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> firstName + " " +<span style="color: rgba(0, 0, 0, 1)"> lastName;
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span>   }<span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>   <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> firstName;
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">}   
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">10</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> let result1 = buildName("Bob");<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> works correctly now</span>
<span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">console.log(result1);
</span><span style="color: rgba(0, 128, 128, 1)">13</span> let result2 = buildName("Bob", "Adams", "Sr.");<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> error, too many parameters</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> let result3 = buildName("Bob", "Adams");<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ah, just right</span></pre>
</div>
<p><span style="color: rgba(0, 0, 255, 1)">2.3 剩余参数</span></p>
<p>关于剩余参数其本质就是ES6的收集(res)语法,使用"..."将多余的参数收集,但是TypeScript转换到ES5的js代码时还是需要使用arguments来实现,毕竟ES5版本中还没有收集(res)语法。详细可以了解ES6入门一:块级作用域(let&amp;const)、spread展开、rest收集</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> buildName(firstName: string, ...restOfName: string[]) {
</span><span style="color: rgba(0, 128, 128, 1)">2</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> firstName + " " + restOfName.join(" "<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">4</span>
<span style="color: rgba(0, 128, 128, 1)">5</span> let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");</pre>
</div>
<p>但是需要注意,收集语法产生的数据必然是数组,所以必须使用数组类型。</p>
<h2 style="background-color: rgba(41, 78, 128, 1); border-radius: 5px">&nbsp;三、TypeScript函数的this与箭头函数</h2>
<p>关于this指向在JavaScript中一直是比较容易被它击晕的一个知识点,不要担心,我这里有一篇博客包治百病:JavaScript中的this指向规则</p>
<p>当然ES6的相关语法产生的this指向规则变化这里也有:ES6入门五:箭头函数、函数与ES6新语法</p>
<p>当然好不了严格模式的this指向问题:JavaScript严格模式</p>
<p>TypeScript并不改变JavaScript的this指向规则,而是在IDE中提供了更友好的警告提示,这个功能需要在tsconfig.json中通过"noImplicitThis": true开启。我们知道在JavaScript中this指向规则是比较复杂的,而TypeScript也根据这些规则做出了相应的调整,这里关于TypeScript函数的this指向其实就是了解"noImplicitThis"给我们的提示规则是什么?</p>
<p><span style="color: rgba(0, 0, 255, 1)">3.1 TypeScript对象返回函数中的this会警告提示:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> let obj =<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>   strs : ["aaa","bbb","ccc","ddd"<span style="color: rgba(0, 0, 0, 1)">],
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span>   fun:<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(){
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">function</span>() { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">这里会提示this出错,因为在严格模式下this可能为undefined,在TypeScript中IDE识别this类型为any,所以被认为可能出现undefined情况</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span>       let index = Math.floor(Math.random() * <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.strs.length);
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span>       <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.strs;
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 255, 1)">var</span> fun =<span style="color: rgba(0, 0, 0, 1)"> obj.fun();
</span><span style="color: rgba(0, 128, 128, 1)">11</span> console.log(fun());</pre>
</div>
<p>&nbsp;这个问题可以使用箭头函数来解决:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> let obj =<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>   strs : ["aaa","bbb","ccc","ddd"<span style="color: rgba(0, 0, 0, 1)">],
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span>   fun:<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(){
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>   <span style="color: rgba(0, 0, 255, 1)">return</span> () =&gt; { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">通过箭头函数解决</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span>       let index = Math.floor(Math.random() * <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.strs.length);
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span>       <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.strs;
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 255, 1)">var</span> fun =<span style="color: rgba(0, 0, 0, 1)"> obj.fun();
</span><span style="color: rgba(0, 128, 128, 1)">11</span> console.log(fun());</pre>
</div>
<p><span style="color: rgba(0, 0, 255, 1)">3.2 this作为函数参数,不会出现错误提示,这一点需要注意,因为在原生JavaScritp种这种写法会直接出现语法错误。例如示例中这样写:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">function</span> f(<span style="color: rgba(0, 0, 255, 1)">this</span>:<span style="color: rgba(0, 0, 255, 1)">void</span>){<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">这里你可以给形参任意TypeScript类型都不会报错</span>
<span style="color: rgba(0, 128, 128, 1)">2</span>   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">很遗憾这里并不会报错</span>
<span style="color: rgba(0, 128, 128, 1)">3</span> }</pre>
</div>
<p>这里有几方面的原因,严格模式下函数只执行内部this都是指向undefined,如果函数被对象调用this必然也就指向调用函数的对象。更关键的是被写在形参内的this根本就不会被TypeScript编译到原生js代码中,这里不报错其实是TypeScript将这个低级的错误帮你自动处理了,所以就静默了这个错误提示。</p>
<p>关于this作为参数在TypeScript中还有另一个功能,就是帮助函数维持this指向,例如官方这个示例:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">interface Card {
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)">    suit: string;
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)">    card: number;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">interface Deck {
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">    suits: string[];
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">    cards: number[];
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>   createCardPicker(<span style="color: rgba(0, 0, 255, 1)">this</span>: Deck): () =&gt;<span style="color: rgba(0, 0, 0, 1)"> Card;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">10</span> let deck: Deck =<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">11</span>   suits: ["hearts", "spades", "clubs", "diamonds"<span style="color: rgba(0, 0, 0, 1)">],
</span><span style="color: rgba(0, 128, 128, 1)">12</span>   cards: Array(52<span style="color: rgba(0, 0, 0, 1)">),
</span><span style="color: rgba(0, 128, 128, 1)">13</span>   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> NOTE: The function now explicitly specifies that its callee must be of type Deck</span>
<span style="color: rgba(0, 128, 128, 1)">14</span>   createCardPicker: <span style="color: rgba(0, 0, 255, 1)">function</span>(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">: Deck) {
</span><span style="color: rgba(0, 128, 128, 1)">15</span>         <span style="color: rgba(0, 0, 255, 1)">return</span> () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 128, 128, 1)">16</span>             let pickedCard = Math.floor(Math.random() * 52<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">17</span>             let pickedSuit = Math.floor(pickedCard / 13<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">18</span>
<span style="color: rgba(0, 128, 128, 1)">19</span>             <span style="color: rgba(0, 0, 255, 1)">return</span> {suit: <span style="color: rgba(0, 0, 255, 1)">this</span>.suits, card: pickedCard % 13<span style="color: rgba(0, 0, 0, 1)">};
</span><span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">23</span>
<span style="color: rgba(0, 128, 128, 1)">24</span> let cardPicker =<span style="color: rgba(0, 0, 0, 1)"> deck.createCardPicker();
</span><span style="color: rgba(0, 128, 128, 1)">25</span> let pickedCard =<span style="color: rgba(0, 0, 0, 1)"> cardPicker();
</span><span style="color: rgba(0, 128, 128, 1)">26</span>
<span style="color: rgba(0, 128, 128, 1)">27</span> alert("card: " + pickedCard.card + " of " + pickedCard.suit);</pre>
</div>
<p>上面这段代码中14行的createCardPicker: function(this: Deck){}被编译成了这样:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> createCardPicker: <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
</span><span style="color: rgba(0, 128, 128, 1)">2</span>         <span style="color: rgba(0, 0, 255, 1)">var</span> _this = <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">3</span> }</pre>
</div>
<p>上面这种代码是我们常用维持this指向的手段,在定义接口时常见的代码,在TypeScript中它使用this作为参数的方式来实现,这样的处理方式可以非常明显的看到this指向了对象自身,并且如果这个方法被赋值给其他对象变量时同样会静默这个this参数的错误,而其他对象在TypeScript严格的变量类型语法中也可能获取这个方法作为自身参数。</p>
<p><span style="color: rgba(0, 0, 255, 1)">3.3 this在回调函数中如何维持this指向?下面是将官方文档代码补全的示例:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">interface UIElement {
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>   addClickListener(onclick: (<span style="color: rgba(0, 0, 255, 1)">this</span>: <span style="color: rgba(0, 0, 255, 1)">void</span>, e: Event) =&gt; <span style="color: rgba(0, 0, 255, 1)">void</span>): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">class Handler {
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">info: string;
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">constructor(infoStr:string){
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>   <span style="color: rgba(0, 0, 255, 1)">this</span>.info =<span style="color: rgba(0, 0, 0, 1)"> infoStr;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">10</span>   onClickGood = (e: Event) =&gt; {<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">通过箭头函数来保持函数内部this不变</span>
<span style="color: rgba(0, 128, 128, 1)">11</span>       <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> can't use this here because it's of type void!</span>
<span style="color: rgba(0, 128, 128, 1)">12</span>       console.log(<span style="color: rgba(0, 0, 255, 1)">this</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">指向Handler的实例对象</span>
<span style="color: rgba(0, 128, 128, 1)">13</span>       console.log(<span style="color: rgba(0, 0, 255, 1)">this</span>.info);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">info</span>
<span style="color: rgba(0, 128, 128, 1)">14</span>       console.log('clicked!'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">17</span> let h = <span style="color: rgba(0, 0, 255, 1)">new</span> Handler('info'<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)">class uiElementClass implements UIElement{
</span><span style="color: rgba(0, 128, 128, 1)">19</span>   addClickListener(onclick: (<span style="color: rgba(0, 0, 255, 1)">this</span>: <span style="color: rgba(0, 0, 255, 1)">void</span>, e: Event) =&gt; <span style="color: rgba(0, 0, 255, 1)">void</span>): <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 128, 128, 1)">20</span>   onclick(<span style="color: rgba(0, 0, 255, 1)">new</span> Event('event'<span style="color: rgba(0, 0, 0, 1)">));
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">23</span> let uiElement:uiElementClass = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> uiElementClass();
</span><span style="color: rgba(0, 128, 128, 1)">24</span> uiElement.addClickListener(h.onClickGood);</pre>
</div>
<h2 style="background-color: rgba(41, 78, 128, 1); border-radius: 5px">&nbsp;四、TypeScript函数重载</h2>
<p>&nbsp;关于TypeScript函数我想了好久就是不知道怎么解析这个东西,照着示例套吧,我也只能复制官方代码放这里了。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> let suits = ["hearts", "spades", "clubs", "diamonds"<span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> pickCard(x: {suit: string; card: number; }[]): number;
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> pickCard(x: number): {suit: string; card: number; };
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> pickCard(x:any): any {
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span>   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Check to see if we're working with an object/array</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span>   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> if so, they gave us the deck and we'll pick the card</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span>   <span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">typeof</span> x == "object"<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>         let pickedCard = Math.floor(Math.random() *<span style="color: rgba(0, 0, 0, 1)"> x.length);
</span><span style="color: rgba(0, 128, 128, 1)">10</span>         <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> pickedCard;
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">12</span>   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Otherwise just let them pick the card</span>
<span style="color: rgba(0, 128, 128, 1)">13</span>   <span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">typeof</span> x == "number"<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 128, 1)">14</span>         let pickedSuit = Math.floor(x / 13<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">15</span>         <span style="color: rgba(0, 0, 255, 1)">return</span> { suit: suits, card: x % 13<span style="color: rgba(0, 0, 0, 1)"> };
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)">    }
</span><span style="color: rgba(0, 128, 128, 1)">17</span> <span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">18</span>
<span style="color: rgba(0, 128, 128, 1)">19</span> let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4<span style="color: rgba(0, 0, 0, 1)"> }];
</span><span style="color: rgba(0, 128, 128, 1)">20</span> let pickedCard1 =<span style="color: rgba(0, 0, 0, 1)"> myDeck;
</span><span style="color: rgba(0, 128, 128, 1)">21</span> alert("card: " + pickedCard1.card + " of " +<span style="color: rgba(0, 0, 0, 1)"> pickedCard1.suit);
</span><span style="color: rgba(0, 128, 128, 1)">22</span>
<span style="color: rgba(0, 128, 128, 1)">23</span> let pickedCard2 = pickCard(15<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 128, 1)">24</span> alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);</pre>
</div>

</div>
<div id="MySignature" role="contentinfo">
    ——生命自会找到蓬勃之路。<br><br>
来源:https://www.cnblogs.com/ZheOneAndOnly/p/11780518.html
頁: [1]
查看完整版本: TypeScript入门三:TypeScript函数类型