• TypeScript函数类型
  • TypeScript函数的参数
  • TypeScript函数的this与箭头函数
  • TypeScript函数重载

一、TypeScript函数类型

在上一篇博客中已经对声明TypeScript类型变量已经做了初步的解析,这里先回顾以下:

  1. //声明函数
  2. function add1(x:number,y:number):number{
  3. return x+y;
  4. }
  5.  
  6. let add2 = function(x:number,y:number):number{
  7. return x + y;
  8. }
  9.  
  10. //定义函数类型
  11. type myAdd = (baseValue: number, increment: number) => number;
  12. //根据函数类型声明函数变量
  13. let myAdd1:myAdd = function(x:number,y:number) : number{
  14. return x + y;
  15. }
  16. let myAdd2:myAdd = function(x:number,y:number) : number{
  17. return x - y;
  18. }
  19.  
  20. let hintStamp(str:string):void{
  21. console.log(str);
  22. }

关于函数类型有一点需要注意,需要使用type关键字并使用等号"="赋值类型;如果使用let声明并使用冒号冒“:”表示的是声明一个函数变量,并且这个函数变量有指定的类型,这个变量不能作为函数类型,只能给它自己赋值指定类型的函数。

二、TypeScript函数的参数

2.1 根据函数类型声明的函数变量,函数的实际参数名称可以不与函数类型的参数名称一致,这一点与对象类型Object的字段有点区别;

  1. type myAdd = (baseValue: number, increment: number) => number;
  2. let myAdd1:myAdd = function(a:number,b:number) : number{
  3. return a + b;
  4. }
  5. let myAdd2:myAdd = function(x:number,y:number) : number{
  6. return x - y;
  7. }

2.2 可选参数与默认参数:

这部非内容在官方文档中有详细的说明,这里简要的解析以下,如果有不明白的建议查看官方文档。

可选参数意思就是函数的参数在实际调用函数时,可以不需要全部对应传入,但是在定义函数类型时,必须设定默认参数。

  1. //示例:在定义函数类型时,给参数b设定了默认参数:'TypeScript'
  2. function foo (a: string,b = 'TypeScript'): void{
  3. console.log(a + ':' + b);
  4. }
  5. foo('hello');//hello:TypeScript

设置了默认参数,就不需要设置参数的类型了,TypeScript的IDE会主动为我们推断出参数的类型,也就是默认值的类型,如果给可选参数传值就必须对应默认参数的类型。

除了设置既定的默认参数以外,还可以使用(参数名+?)的方式设置非特定参数,但是设置默认非特定参数需要设置默认参数的类型(参数名?:类型)。这种不设定特定值的可选参数,调用函数时不给这个可选参数传值的话就会默认为undefined。

  1. //这是官方文档中的一个示例:
  2. function buildName(firstName: string, lastName?: string) {
  3. if (lastName){
  4.  
  5. return firstName + " " + lastName;
  6. }else{
  7. return firstName;
  8. }
  9. }
  10.  
  11. let result1 = buildName("Bob"); // works correctly now
  12. console.log(result1);
  13. let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
  14. let result3 = buildName("Bob", "Adams"); // ah, just right

2.3 剩余参数

关于剩余参数其本质就是ES6的收集(res)语法,使用"..."将多余的参数收集,但是TypeScript转换到ES5的js代码时还是需要使用arguments来实现,毕竟ES5版本中还没有收集(res)语法。详细可以了解ES6入门一:块级作用域(let&const)、spread展开、rest收集

  1. function buildName(firstName: string, ...restOfName: string[]) {
  2. return firstName + " " + restOfName.join(" ");
  3. }
  4.  
  5. let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

但是需要注意,收集语法产生的数据必然是数组,所以必须使用数组类型。

三、TypeScript函数的this与箭头函数

关于this指向在JavaScript中一直是比较容易被它击晕的一个知识点,不要担心,我这里有一篇博客包治百病:JavaScript中的this指向规则

当然ES6的相关语法产生的this指向规则变化这里也有:ES6入门五:箭头函数、函数与ES6新语法

当然好不了严格模式的this指向问题:JavaScript严格模式

TypeScript并不改变JavaScript的this指向规则,而是在IDE中提供了更友好的警告提示,这个功能需要在tsconfig.json中通过"noImplicitThis": true开启。我们知道在JavaScript中this指向规则是比较复杂的,而TypeScript也根据这些规则做出了相应的调整,这里关于TypeScript函数的this指向其实就是了解"noImplicitThis"给我们的提示规则是什么?

3.1 TypeScript对象返回函数中的this会警告提示:

  1. let obj = {
  2. strs : ["aaa","bbb","ccc","ddd"],
  3. fun:function(){
  4. return function() { //这里会提示this出错,因为在严格模式下this可能为undefined,在TypeScript中IDE识别this类型为any,所以被认为可能出现undefined情况
  5. let index = Math.floor(Math.random() * this.strs.length);
  6. return this.strs[index];
  7. }
  8. }
  9. }
  10. var fun = obj.fun();
  11. console.log(fun());

这个问题可以使用箭头函数来解决:

  1. let obj = {
  2. strs : ["aaa","bbb","ccc","ddd"],
  3. fun:function(){
  4. return () => { //通过箭头函数解决
  5. let index = Math.floor(Math.random() * this.strs.length);
  6. return this.strs[index];
  7. }
  8. }
  9. }
  10. var fun = obj.fun();
  11. console.log(fun());

3.2 this作为函数参数,不会出现错误提示,这一点需要注意,因为在原生JavaScritp种这种写法会直接出现语法错误。例如示例中这样写:

  1. function f(this:void){//这里你可以给形参任意TypeScript类型都不会报错
  2. //很遗憾这里并不会报错
  3. }

这里有几方面的原因,严格模式下函数只执行内部this都是指向undefined,如果函数被对象调用this必然也就指向调用函数的对象。更关键的是被写在形参内的this根本就不会被TypeScript编译到原生js代码中,这里不报错其实是TypeScript将这个低级的错误帮你自动处理了,所以就静默了这个错误提示。

关于this作为参数在TypeScript中还有另一个功能,就是帮助函数维持this指向,例如官方这个示例:

  1. interface Card {
  2. suit: string;
  3. card: number;
  4. }
  5. interface Deck {
  6. suits: string[];
  7. cards: number[];
  8. createCardPicker(this: Deck): () => Card;
  9. }
  10. let deck: Deck = {
  11. suits: ["hearts", "spades", "clubs", "diamonds"],
  12. cards: Array(52),
  13. // NOTE: The function now explicitly specifies that its callee must be of type Deck
  14. createCardPicker: function(this: Deck) {
  15. return () => {
  16. let pickedCard = Math.floor(Math.random() * 52);
  17. let pickedSuit = Math.floor(pickedCard / 13);
  18.  
  19. return {suit: this.suits[pickedSuit], card: pickedCard % 13};
  20. }
  21. }
  22. }
  23.  
  24. let cardPicker = deck.createCardPicker();
  25. let pickedCard = cardPicker();
  26.  
  27. alert("card: " + pickedCard.card + " of " + pickedCard.suit);

上面这段代码中14行的createCardPicker: function(this: Deck){}被编译成了这样:

  1. createCardPicker: function () {
  2. var _this = this;
  3. }

上面这种代码是我们常用维持this指向的手段,在定义接口时常见的代码,在TypeScript中它使用this作为参数的方式来实现,这样的处理方式可以非常明显的看到this指向了对象自身,并且如果这个方法被赋值给其他对象变量时同样会静默这个this参数的错误,而其他对象在TypeScript严格的变量类型语法中也可能获取这个方法作为自身参数。

3.3 this在回调函数中如何维持this指向?下面是将官方文档代码补全的示例:

  1. interface UIElement {
  2. addClickListener(onclick: (this: void, e: Event) => void): void;
  3. }
  4.  
  5. class Handler {
  6. info: string;
  7. constructor(infoStr:string){
  8. this.info = infoStr;
  9. }
  10. onClickGood = (e: Event) => {//通过箭头函数来保持函数内部this不变
  11. // can't use this here because it's of type void!
  12. console.log(this);//指向Handler的实例对象
  13. console.log(this.info);//info
  14. console.log('clicked!');
  15. }
  16. }
  17. let h = new Handler('info');
  18. class uiElementClass implements UIElement{
  19. addClickListener(onclick: (this: void, e: Event) => void): void{
  20. onclick(new Event('event'));
  21. }
  22. }
  23. let uiElement:uiElementClass = new uiElementClass();
  24. uiElement.addClickListener(h.onClickGood);

四、TypeScript函数重载

关于TypeScript函数我想了好久就是不知道怎么解析这个东西,照着示例套吧,我也只能复制官方代码放这里了。

  1. let suits = ["hearts", "spades", "clubs", "diamonds"];
  2.  
  3. function pickCard(x: {suit: string; card: number; }[]): number;
  4. function pickCard(x: number): {suit: string; card: number; };
  5. function pickCard(x:any): any {
  6. // Check to see if we're working with an object/array
  7. // if so, they gave us the deck and we'll pick the card
  8. if (typeof x == "object") {
  9. let pickedCard = Math.floor(Math.random() * x.length);
  10. return pickedCard;
  11. }
  12. // Otherwise just let them pick the card
  13. else if (typeof x == "number") {
  14. let pickedSuit = Math.floor(x / 13);
  15. return { suit: suits[pickedSuit], card: x % 13 };
  16. }
  17. }
  18.  
  19. let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
  20. let pickedCard1 = myDeck[pickCard(myDeck)];
  21. alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);
  22.  
  23. let pickedCard2 = pickCard(15);
  24. alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);

TypeScript入门三:TypeScript函数类型的更多相关文章

  1. TypeScript魔法堂:函数类型声明其实很复杂

    前言 江湖有传"动态类型一时爽,代码重构火葬场",由于动态类型语言在开发时不受数据类型的约束,因此非常适合在项目原型阶段和初期进行快速迭代开发使用,这意味着项目未来将通过重写而非重 ...

  2. typeScript入门基础 (2): 数据 类型, 函数定义

    1.   number , boolean, string, null, undefind  枚举, any, array数组, 元祖, 2...枚举,需要的注意点,  下一个图,就是为什么yello ...

  3. TypeScript入门五:TypeScript的接口

    TypeScript接口的基本使用 TypeScript函数类型接口 TypeScript可索引类型接口 TypeScript类类型接口 TypeScript接口与继承 一.TypeScript接口的 ...

  4. TypeScript基础类型,类实例和函数类型声明

    TypeScript(TS)是微软研发的编程语言,是JavaScript的超集,也就是在JavaScript的基础上添加了一些特性.其中之一就是类型声明. 一.基础类型 TS的基础类型有 Boolea ...

  5. Typescript 学习笔记三:函数

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  6. typeScript入门(二)函数与类

    3.ts的函数 1)函数的返回值和参数 在函数的定义需要定义其的返回值可以void,来表示没有返回值 函数参数的定义,举个例子分析下吧 name:string,age?:number=23 冒号后面是 ...

  7. TypeScript 入门自学笔记 — 类型断言(二)

    码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14558034.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...

  8. TypeScript入门-函数

    ▓▓▓▓▓▓ 大致介绍 TypeScript为JavaScript函数添加了额外的功能,让我们可以更容易地使用.TypeScript中的函数也包括JavaScript中最常见的两种函数 functio ...

  9. TypeScript 函数-函数类型

    //指定参数类型 function add(x:number,y:number){ console.log("x:"+x); // reutrn(x+y); } //指定函数类型 ...

随机推荐

  1. ThinkPHP使用smarty模板引擎的方法

    ThinkPHP支持多种php模板引擎,可以根据个人需要加以配置.下面我们以Smarty模板引擎为例,给大家说说具体的操作流程! 首先去Smarty官网上下载一个Smarty.本站下载地址:http: ...

  2. tensorflow查看ckpt各节点名称

    from tensorflow.python import pywrap_tensorflowimport os checkpoint_path=os.path.join('output/res101 ...

  3. css简单学习属性

      1:内联元素和块级元素 1).块级元素,默认是:内联元素可以变成块级元素,块级元素可以变成内联元素. <!DOCTYPE html> <html lang="en&qu ...

  4. 模型压缩-L1-norm based channel pruning(Pruning Filters for Efficient ConvNets)

    论文笔记——PRUNING FILTERS FOR EFFICIENT CONVNETS  转载:https://www.cnblogs.com/zhonghuasong/p/7642000.html ...

  5. xampp 启动mysql 显示busy

    1.端口被占用问题:2.默认3306端口并没有被占用:3.删除xampp\mysql\data\下的ibdata1再重启:4.没装其他mysql.

  6. Nginx-windows

    1.下载 http://nginx.org/ 选择最新稳定版本,例如nginx-1.15.5 mainline version has been released. 点击后,跳转页面,选择Stable ...

  7. 怎么理解linux作业(job),与进程(process)的关系

    1.相关概念: shell :命令解释器,其实就是一个脚本语言解释器,有很多种(bash,ash,tcsh等),最常用的是bash. job(作业): 是相对shell 来说的,在shell中执行一条 ...

  8. 通过bat批处理程序如何实现在多个txt文件后面加上相同的一行文字

    通过bat批处理程序如何实现在多个txt文件后面加上相同的一行文字 set/p a=输入要增加的文字 for /f "delims=" %%i in ('dir /b *.txt' ...

  9. OpenCV.3.4.6.附加依赖项

    ZC:VS2015 "项目属性 --> 链接器--> 输入--> 附加依赖项" 中 添加内容 1.E:\OpenCV_something\opencv-3.4.6 ...

  10. 洛谷 题解 P1353 【[USACO08JAN]跑步Running】

    动态规划 状态 dp[i][j]表示第i分钟疲劳值为j的最大值 初始 全部都为一个最小值"0" 转移 考虑休息和走 如果当前疲劳值比时间要大,显然不可能出现这种情况 如果比时间小 ...