天天看点

函数_TypeScript笔记5

一.类型

函数的类型分为两部分:

参数:各个参数的类型

返回值:返回值的类型

例如:

带类型的函数声明足够表达一个函数的类型信息,但无法复用。那么有办法复用一个函数的类型吗?

有。把类型抽离出来就可以复用了,姑且称之为类型描述

类型描述

可以通过箭头函数语法描述函数的类型:

箭头(=>)左侧是参数及其类型,右侧是返回值类型,都是语法结构的一部分,不可缺省:

P.S.注意到上面示例只声明了一份类型,是因为右边匿名函数的类型能够根据左侧类型声明自动推断出来,称之为语境类型推断(contextual typing)

另外,类型描述里的参数名只是可读性需要,不要求类型描述中的参数名与真实参数名一致,例如:

P.S.实际上,还有另一种描述函数类型的方式:接口,具体见接口_TypeScript笔记3

二.参数

可选参数

JavaScript里参数默认都是可选的(不传的默认undefined),而TypeScript认为每个参数都是必填的,除非显式声明可选参数:

与可选属性的语法类似,紧跟在参数名后面的?表示该参数可选,并且要求可选参数必须出现在必填参数之后(所以想要firstName可选,lastName必填的话,只能改变参数顺序)

默认参数

默认参数语法与ES规范一致,例如:

从含义上看,默认参数当然是可选的(不填就走默认值),因此,可以认为默认参数是特殊的可选参数,甚至连类型描述也是兼容的:

二者类型完全一致,所以,类型描述并不能完整表达默认参数(仅能表达出可选的含义,默认值丢失了)

另一个区别是,默认参数不必出现在必填参数之后,例如:

显式传入undefined占位,具体见三.默认参数

剩余参数

与ES6不定参数语法一致:

剩余参数也是可选的,相当于不限数量的可选参数:

另外,类型描述中也采用了相同的语法:

三.this

this在JavaScript不那么容易驾驭,例如:

this的类型

特殊的,TypeScript能够描述this的类型,例如:

其中this是个假参数,并且要求必须作为第一个参数:

this也像普通参数一样进行类型检查,能够提前暴露出类似的错误:

P.S.另外,可以开启--noImplicitThis编译选项,强制要求所有this必须有显式的类型声明

四.重载

类似于Java里的重载:

(摘自Types of polymorphism in java- Runtime and Compile time polymorphism)

简言之,能让同名函数的不同版本共存。不同版本体现在参数差异上:

参数数量

参数顺序

参数类型

这3个特征中只要有一个不同就算重载。如果都相同,就认为是重复声明的方法(Duplicate Method),并抛出编译错误:

TypeScript里也有重载的概念,但与Java重载有一些差异,例如:

看起来非常合理,但在TypeScript里会报错:

编译结果是这样(TypeScript编译报错并不影响代码生成,具体见类型系统):

因为JavaScript不支持重载,(同一作用域下的)方法会覆盖掉先声明的同名方法,无论函数签名是否相同。因此,TypeScript里的重载能力受限,仅体现在类型上:

同样,这些重载类型声明仅作用于编译时,因此也有类似于模式匹配的特性:

上例中先声明的更宽泛的any版本成功匹配,因此并没有如预期地匹配到更准确的number版本,

所以,应该把最宽泛的版本放到最后声明: