TypeScript基础教程
TypeScript基础教程
TypeScript
类型
typescript提供类型支持,typescript不仅支持原有的JavaScript类型,例如字符串、数字、数组等,还支持一些新的类型,例如元组、void、枚举等。
常用类型
基本类型
boolean
number
string
null
undefined
复杂类型
Array
object
扩展类型(ts新增的类型)
Tuple
Enum
Any
Never
Void
Unknown
union(联合类型)
intersection(交叉类型)
数组与元组
数组有两种方式定义元素类型
元组与数组类似,但是元组更加严格,元组适用于已知所有元素个数和类型的情况下。
void与never
void通常用于表示函数没有显式返回值,或者值为null或undefined的变量。
never表示永不存在的值,常见与总是报错或根本不会返回的函数。
any和unknown
any可以是任意类型,这将跳过类型检查
unknown 与 any类似,它们的不同之处在于,虽然它们都可以是任何类型,但是当 unknown 类型被确定是某个类型之前,它不能被进行任何操作比如实例化、getter、函数执行等等
如果你事先不确定需要用哪个类型,你可以先定义any类型或者unknown,之后再进行类型判断,但是any会跳过类型检查,因此建议使用unknown
类型断言
有时候你会遇到这样的情况,你会比TypeScript更了解某个值的详细信息,你可以手动告诉ts值的类型,ts则会相信你并将你给定的类型当做该值的类型。 类型断言有两种方式,尖括号或者使用as
一般情况下两种方式都可以,但是在jsx中只有as才被运行,因此建议统一使用as语法。
接口
基础
接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。例如定义一个对象所有属性的类型。
const obj: Ob表示obj变量需要实现接口Ob所定义的属性和方法。
可选、只读
接口里的属性和方法并非全部都需要实现,假如你想定义一个可选的属性,只需要运用?:即可。
readonly则表示该属性一旦声明后就不能再被改变。
函数类型
接口不仅仅用来定义对象类型,也可以用来定义函数类型。为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。
函数参数名称可以和接口参数名称不同,但是类型必须相同。
方法类型
接口除了定义对象属性,也可以定义对象方法
可索引的类型
可索引类型具有一个 索引签名,它描述了对象索引的类型,还有相应的索引返回值类型。
[name: number]: string表示对象的key只能是number类型,值是string的属性,其中name只是为了可读性,没有实际意义,属性名可以不为name。
另外索引类型仅可以使用number和string。
索引签名[name: number]: string并没有限制必须要是number类型的key,它限制的是:所有number类型的key所对应的值必须是string。
继承接口
和类一样,接口也可以相互继承。 这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。
合并接口
合并接口非常简单,当声明了多个同名的接口时,ts就会自动合并该接口
字面量类型
字符串、数字和布尔值这三个类型可以使用字面量类型,通常是在定义常量的时候使用
除了直接使用字面量外,也可以使用类型别名来实现相同的效果。
类型别名
实现类型别名
运用type关键字,创建类型别名
type能做的不只是上面所写的那些,你可以使用类型别名为任何类型指定名称,事实上,type和interface很相似。 ### 合并type 你可以通过&字符来合并type
类型别名和接口之间的差异
类型别名和接口非常相似,在许多情况下,您可以自由选择它们。几乎接口的所有功能都可以用type实现,关键的区别在于类型别名不能被重新打开来添加新的属性,而接口总是可扩展的。
函数
函数类型
直接在函数声明时定义参数类型和返回值类型。
书写完整的函数类型
通常将完整的函数类型写到接口里,以达到复用的目的。
可选参数、默认参数与剩余参数
可选参数 用?:来定义一个可选参数,注意可选参数一定要在必填参数后面。
默认参数
默认参数也会被认为是可选参数,并且typescript会对默认值进行类型推导,因此传入对默认参数类型必须和默认值相同,当然你也可以手动指定默认参数的类型。
剩余参数
箭头函数
ES6新增了箭头函数,你也可以在ts中为箭头函数定义参数和返回值的类型。
可实例化
可实例化仅仅是可调用的一种特殊情况,它使用 new 作为前缀。它意味着你需要使用 new 关键字去调用它:
函数重载
TypeScript中的函数重载可以定义多个函数声明,其中函数的参数必须不同,类型可以相同也可以不同。当我们调用重载函数时,TypeScript会根据传入参数的类型和个数来决定调用哪个函数,从而使函数可以返回不同的结果。
下面是一个简单的函数重载的例子:
泛型
泛型变量
某些时候我们会多次使用到某个类型,但是我们事先却又不知道它具体是哪个类型,例如一个函数接受某个类型的参数,并且需要返回相同类型的值。
如果事先确定参数类型,那么就很容易直接指定类型,但是假如它并不特定是某个类型,它可能是泛指一些类型,那么这个时候就可以使用泛型。
泛型在使用上可以指定类型或者不指定(ts进行类型推导)
泛型接口
泛型类
泛型类看上去与泛型接口差不多。 泛型类使用( <>)括起泛型类型,跟在类名后面。
类有两部分:静态部分和实例部分。 泛型类指的是实例部分的类型,所以类的静态属性不能使用这个泛型类型。
泛型约束
有时候需要约束泛型变量,例如要求arg必须包含num属性,此时可以使用泛型约束
枚举
数字枚举
数字枚举既可以正向映射,也可以反向映射。
enum默认是数字枚举,这类似于
也可以显式地指定成员的值,后面没有指定的值则自动递增。
字符串枚举
字符串枚举就是使用字符串作为枚举成员的值
字符串枚举不支持反向映射
const枚举
常量枚举只能使用常量枚举表达式,并且不同于常规的枚举,它们在编译阶段会被删除,这在对性能要求很高的场景下会很有用。
联合枚举类型
枚举可以当作联合类型。
异构枚举
ts允许混合数字枚举和字符串枚举,但是一般情况很少使用。
可选链
ES6中新增了可选链。
在一些情况下,你可能确定某个属性存在,但是ts可能会假设它不存在,这个时候你可以使用非空断言运算符。
当然在这种情况下另一种的方法是进行检查
类型判断(类型范围缩小)
在上面代码中,padStart是字符串特有的方法,但是ts认定参数a是一个字符串和数字的联合类型,因此会引发报错,对于这种情况我们需要缩小类型范围,让ts类型系统认定参数a是一个字符串。 解决的方法也很简单,就是将类型范围缩小至允许的类型。下面谈谈几种常见的方法。 ### typeof 对多大多数原始类型(null除外)和一些引用类型(例如function类型)来说,使用typeof来缩小类型范围是一个很好的选择。
真值
严格相等
如果一个大范围的类型严格等于(===)某个小范围的值,那么就能将类型范围缩小。
这是借助了严格相等需要类型也相等的特性,如果把严格相等换成普通相等(==)则无法实现效果。 ### in 借助in关键字,可以判断某个属性是否存在对象中。
需要注意的是in关键字不仅会检查实例属性,还会检查原型对象上的属性,当属性存在于对象的原型对象中时也会返回true。
instanceof
instanceof可以用来检查引用类型,语法是实例 instanceof 构造函数,但是要注意它的原理是遍历左侧实例的原型链,找到与右侧构造函数相同的原型对象时返回true,也就是说以下几种语句都返回true
构造函数的静态方法
基于instanceof的缺陷,ES6在一些构造函数上增加了检测类型的静态方法,例如Array.isArray和Number.isNaN。
参考
最后更新于