typescript-函数的类型
https://www.cnblogs.com/wzy1569178479/p/7364340.html
1.函数声明
1 function student(x:string,y:number):string{ 2 return `我是${x},今年${y}岁`; 3 } 4 5 console.log(student("wzy",22)); // 我是wzy,今年22岁
形式和JavaScript中的函数声明一样,不一样的是什么呢?
(1)指定了参数的类型(因为有类型检查,所以要遵循),随后指定了返回值的类型,
这个时候返回值类型可以省略,因为typescript会根据返回语句自动推断出返回值的类型。
(2)参数不可多不可少,只能刚刚好,且和顺序有关。
1 function student(x:string,y:number){ 2 console.log(`我是${x},今年${y}岁`); 3 } 4 5 student(22,"wzy"); 6 // Argument of type '22' is not assignable to parameter of type 'string'.
2.函数表达式
有些话总是需要照抄下来的,比如下面这两句话
如果要我们现在写一个对函数表达式(Function Expression)的定义,可能会写成这样:
1 let student = function(x:string,y:number):string{ 2 return `我是${x},今年${y}岁`; 3 } 4 5 console.log(student("wzy",22)); // 我是wzy,今年22岁
这是可以通过编译的,不过事实上,上面的代码只对等号右侧的匿名函数进行了类型定义,而等号左边的 student
,是通过赋值操作进行类型推论而推断出来的。
如果需要我们手动给 student
添加类型,则应该是这样:
1 let student:(x:string,y:number)=>string = function(x:string,y:number):string{ 2 return `我是${x},今年${y}岁`; 3 } 4 5 console.log(student("wzy",22)); // 我是wzy,今年22岁
这是就需要多谈两句了:
(1)前后参数名称可以不一致
1 let student:(x:string,y:number)=>string = function(name:string,age:number):string{2 return `我是${x},今年${y}岁`;3 }4 // 这样对吗?嗯!好像是哪里不太对~5 // Cannot find name 'x'. 6 // Cannot find name 'y'.7 8 let student:(x:string,y:number)=>string = function(name:string,age:number):string{9 return `我是${name},今年${age}岁`; 10 } 11 // 这样就对了~
(2)我对这种声明函数的方式的理解就是:
let student : (x:string,y:number)=>string = function(name:string,age:number):string{}声明变量 指定函数类型 根据指定函数类型定义函数此时再根据之前讲过的“类型推论”,就有以下这样的声明方式了
1 let student:(x:string,y:number)=>string = function(name,age){ 2 return `我是${name},今年${age}岁`; 3 } 4 5 let student = function(name:string,age:number):string{ 6 return `我是${name},今年${age}岁`; 7 }
据说这叫“按上下文归类”,是类型推论的一种。
(3)之前我们也讲过,当没有返回值的时候要怎样,在这种完整的函数声明的情况下是不可以返回值为空的,这时我们就会想起void
1 let student:(x:string,y:number) = function(name,age){ 2 console.log(`我是${name},今年${age}岁`);3 }4 5 // '=>' expected.6 // 这样是不允许的,也不要妄想 =>"" 这样,人家就没有""这种类型好吗7 8 let student:(x:string,y:number)=>void = function(name,age){ 9 console.log(`我是${name},今年${age}岁`); 10 } 11 // 还是老老实实的这样子吧
3.接口中函数的定义
1 interface Student{ 2 (x:string,y:number):string 3 } 4 5 let str1:Student; 6 str1 = function(x,y){ 7 return `我是${x},今年${y}岁`; 8 }
4.可选参数
之前提到过函数的参数是不可多不可少的,但是也可以像接口那样的形式用?表示可选参数
1 function student(name:string,age:number,sex?:boolean){2 if(sex){3 return `name:${name},age:${age},sex:女`;4 }else{5 return `name:${name},age:${age},sex:未知`;6 }7 }8 9 console.log(student("weizeyang",22,true)); // name:weizeyang,age:22,sex:女 10 console.log(student("weizeyang",22)); // name:weizeyang,age:22,sex:未知
再看看它要注意哪些:
(1)可选参数要放在必需参数后面
(2)肚子好疼,不开心
5.默认参数
在typescript中,可以为函数中的参数设置一个默认值,当用户没有传这个参数或者传的值是undefined时,就显示默认值。
1 function student(name:string,age:number,sex="女"){2 return `name:${name},age:${age},sex:${sex}`;3 }4 5 console.log(student("weizeyang",22,"未知")); 6 // name:weizeyang,age:22,sex:未知7 8 console.log(student("weizeyang",22)); 9 // name:weizeyang,age:22,sex:女 10 11 console.log(student("weizeyang",22,undefined)); 12 // name:weizeyang,age:22,sex:女
千古不无的注意点:
(1)可以看到,默认值的参数识别为可选参数,但不必在必需参数后面。
(2)虽说它是可选参数了耶不必放在必需参数后面了,但是一旦放在必需参数前面,就要明确写上undefined或者值,即不能空这。
这样一来,写在前面也就不算是可选参数了。
1 function student(sex="女",name:string,age:number){2 return `name:${name},age:${age},sex:${sex}`;3 }4 5 console.log(student("未知","weizeyang",22)); 6 // name:weizeyang,age:22,sex:未知7 8 console.log(student("weizeyang",22)); 9 // Expected 3 arguments, but got 2. 10 11 console.log(student(undefined,"weizeyang",22)); 12 // name:weizeyang,age:22,sex:女
不知道别人看得懂这句话不,反正我是看懂说的是啥了。
6.剩余参数
之前讲过的必要参数、默认参数和可选参数表示的都是某一个参数,有时,你想同时操作多个参数,或者你并不知道会有多少个参数会传进来。
在JavaScript中,你可以使用arguments来访问所有传入的参数。
在typescript里,你可以把所有参数收集到一个变量里:
1 function student(age:number,sex:boolean,...name:string[]){ 2 return `我是${name.join("")},年龄${age}`; 3 } 4 5 console.log(student(22,true,"wei","ze","yang")); 6 // 我是weizeyang,年龄22
来吧,注意点:
(1)剩余参数会被当做个数不限的可选参数,可以一个都没有,也可以有任意个。同样要放在必要参数后面。
(2)是数组类型,名字是省略号后面的字段名,可以在函数体内使用这个数组。
(3)当调用函数时,别传入数组,依次传入就行。
7.Lambda表达式和使用this
在JavaScript里,this
的值在函数被调用的时候才会指定。学过JavaScript的都知道this很是让人头疼啊!
1 var student = {2 names: ["wzy", "wyy", "wxy", "yz"],3 getName: function() {4 5 return function(){ 6 var item = Math.floor(Math.random() * 4);7 console.log(this); 8 9 return { 10 name: this.names[item] // Cannot read property 'names' of undefined 11 } 12 } 13 } 14 } 15 16 let sname = student.getName(); 17 console.log("my name is " + sname().name);
7行打印出的是window,因为这里没有对this进行动态绑定
1 "use strict"; // 严格模式2 3 var student = {4 names: ["wzy", "wyy", "wxy", "yz"],5 getName: function() {6 7 return function(){8 var item = Math.floor(Math.random() * 4);9 console.log(this); // undefined 10 11 return { 12 name: this.names[item] // Cannot read property 'names' of undefined 13 } 14 } 15 } 16 } 17 18 let sname = student.getName(); 19 console.log("my name is " + sname().name);
9行打印出的是undefined,看着和上面的好像也没什么差别,实则现在是在JavaScript严格模式下(咱们一直都在),打印出的就是undefined了。
为了解决这个问题,我们可以在函数被返回时就绑好正确的this
。 这样的话,无论之后怎么使用它,都会引用绑定的‘student’对象。
我们把函数表达式变为使用lambda表达式( () => {} )。 这样就会在函数创建的时候就指定了‘this’值,而不是在函数调用的时候。
1 var student = {2 names: ["wzy", "wyy", "wxy", "yz"],3 getName: function() {4 console.log(this);5 // 注意:下面这行是一个lambda,允许我们提前捕捉它6 return () => { 7 var item = Math.floor(Math.random() * 4);8 console.log(this); 9 10 return { 11 name: this.names[item] 12 } 13 } 14 } 15 } 16 17 let sname = student.getName(); 18 console.log("my name is " + sname().name);
在第4,8行打印出了
即student这个对象,大功告成
8.重载
举个栗子:
1 function schools(type:number|string):number|string{2 if(typeof type === "number"){3 return type.toFixed(2);4 }else if(typeof type === "string"){5 return type.substring(0,1);6 }7 }8 9 console.log(schools(1)); // 1.00 10 console.log(schools("wzy")); // w
上面函数的参数和返回值的类型均使用了联合类型的形式,这样一来我们就不能准确的表达我传入的是number类型的返回的就要是number类型得了
这时就要引入重载的概念了
在学Java的时候,重载是这样讲的:函数名相同,函数的参数列表不同(包括参数个数和参数类型),返回值类型可同可不同
网上的例子是这样给出的:
1 function schools(type:number):number;2 function schools(type:string):string;3 function schools(type:number|string):number|string{4 if(typeof type === "number"){5 return type.toFixed(2);6 }else if(typeof type === "string"){7 return type.substring(0,1);8 }9 } 10 11 console.log(schools(1)); // 1.00 12 console.log(schools("wzy")); // w
就是讲这两个函数在上面多声明了几次
需要注意的是:
(1)TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。
再给个栗子:
1 function schools(type:number):number;2 function schools(type:string):string;3 function schools(type:number | string | boolean):number | string | boolean{4 if(typeof type === "number"){5 return type.toFixed(2);6 }else if(typeof type === "string"){7 return type.substring(0,1);8 }else if(typeof type === "boolean"){9 return true; 10 } 11 } 12 13 console.log(schools(1)); // 1.00 14 console.log(schools("wzy")); // w 15 console.log(schools(true)); 16 // Argument of type 'true' is not assignable to parameter of type 'string'.
(2)说明3行的代码并不属于重载部分,这里只有1,2行的函数重载起作用。用除这两种外的其他类型的参数调用schools会产生错误。
(3)1,2行是定义了两个函数,而3行只是对这两个重载函数的实现。
我在知乎上看到的总结是这样说的,因为会有好多人觉得typescript的重载存在的意义不大:
TypeScript 的重载是为了给调用者看,方便调用者知道该怎么调用(同时 tsc 也会进行静态检查以避免错误的调用)。
有助于IDE的代码提示,以及返回值的类型约束。
typescript-函数的类型相关推荐
- typeScript复杂数据类型--任意类型、类型推论、联合类型、对象的类型(接口)、数组的类型、函数的类型
目录 1.任意值 什么是任意值类型 未声明类型的变量 2.类型推论 3. 联合类型 访问联合类型的属性或方法 4.对象的类型--接口 什么是接口 可选属性 任意属性 只读属性 1.任意值 任意值(An ...
- TypeScript Type Innference(类型推断)
在这一节,我们将介绍TypeScript中的类型推断.我们将会讨论类型推断需要在何处用到以及如何推断. 基础 在TypeScript中,在几个没有明确指定类型注释的地方将会使用类型推断来提供类型信息. ...
- typescript利用接口类型声明变量_TypeScript入门指南(基础篇)
戳蓝字「前端技术优选」关注我们哦! 作者:慕晨同学 原文地址:https://github.com/USTB-musion/fee-skills/issues/19 写在前面 ts是拥有类型系统 ...
- typescript函数使用
一.定义函数的方式: 函数声明(Function Declaration) 函数表达式(Function Expression) 用接口定义函数 函数的类型 (1)函数声明 function sumN ...
- TypeScript Type Compatibility 类型兼容性
官方链接 TypeScript 中的类型兼容性基于结构子类型. 结构类型是一种仅基于其成员关联类型的方法.这与 nominal typing 相反.考虑以下代码: interface Pet {nam ...
- TypeScript里的类型为any和泛型的区别
看下面这个TypeScript函数: function identity(arg: any): any {return arg; } 虽然使用any类型后这个函数已经能接收任何类型的arg参数,但是却 ...
- TypeScript笔记(4)—— TypeScript中的类型注解
TypeScript(4):类型注解 [导读]JavaScript是若类型语言,而TypeScript里的类型注解是一种轻量级的为函数或变量添加约束的方式,为我们提供了静态类型分析能力,这样我们就可以 ...
- TypeScript - 函数
前言 本文主要记录下 TypeScript 中的函数,日常学习总结篇. 在 JavaScript 中,函数是构建应用的一块基石,我们可以使用函数抽离可复用的逻辑.抽象模型.封装过程.在 TypeScr ...
- TypeScript 中的类型兼容性
Typescript 乃 JavaScript 子集.只要设置一下编译器为非严格模式,那么所有 JavaScript 代码皆是合法的 TypeScript 代码.为了可以适应不同的场景 TypeScr ...
- TypeScript函数和类
函数介绍 函数是JavaScript应用程序的基础.它帮助你实现抽象层,模拟类,信息隐藏和模块.在TypeScript里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义行为的地方.TypeSc ...
最新文章
- 通知:正式迁移至新博客
- 1024程序员节,你是我们要找的那条锦鲤吗?
- linux 循环shell脚本,shell脚本的使用---for循环
- 钢结构节点输出软件_BIM助力桥梁钢结构设计施工一体化建设
- SAP MM Overall Level 审批的采购申请中行项目里的成本中心必须是同一个!
- 数学之美 系列十 有限状态机和地址识别
- php str cmp,php中整数的strcmp equivalent(intcmp)
- phpcmsV9 用seotitle后面的小横杠分隔符自定义
- Samba配置文件解析
- jsp,jstl checkbox 回显方法
- Viewstub 以及 view.setVisible(GONE/VISIBLE) 的实现原理
- 华为usg6000配置手册_三国志11手机版,问题解决手册 1.4.4版本
- 100位量子计算机算力,最快!我国量子计算机实现算力全球领先
- 国产_系统_加油 by tmddebaba
- ROS多设备组网(WSL+miniPC+Nv Orin)
- Thinkphp6快速入门教程
- 华为鸿蒙手机版要2021开源,鸿蒙系统再起疑云:开源版和手机版完全不同,后者还有安卓彩蛋...
- c语言编程送小狗回家,【原创】《My Sherlock Ⅱ 》(BY C语言概率论)
- Win电源选项设置效果及意义(个人整理)(包含:电源设置,开启卓越模式,睡眠休眠的区别)
- [经济学原理|政治部分]剩余价值理论
热门文章
- 程序员视角的计算机系统 2.1.7 布尔代数的介绍
- 安徽GDP首破3万亿 增长8.02%
- JAVA版本微信管家平台—JeeWx 捷微 4.1 微服务版本发布,微信砍价活动闪亮登场!...
- privoxy Invalid header received from client.
- 糖儿飞教你学C++ Socket网络编程——5.2 TCP通信程序的函数及流程总结
- C++网络编程学习:服务端多线程分离业务处理高负载
- ppp项目跟踪审计为谁服务器,PPP项目跟踪审计研究——以J项目为例
- matlab函数图形模拟器源代码,直接拿走就用
- midi接口 stm32_ALIENTEK MiniSTM32读取midi文件数据出错
- 通过meta代码强制浏览器使用WebKit内核极速模式(解决 meta name=renderer content=webkit 不起作用)