元组:
情景:在地图中,使用经纬度坐标来标记位置信息,可以使用数组来记录坐标,所以该素组中只有两个元素,并且这两个元素都是数值类型的比如:
let Person:numbre[] = [39.5427, 116.2317]
但是使用这种方式的缺点就是:不严谨,因为该类型的数组中可以出现任意多的数字
更好的方式:元组(Tuple)
元组类型是另一种类型的数组,它确切的指导包含多少元素,以及特定索引对应的类型。
let Person:[number, number] = [39.5427, 116.2317]
优点:
(1)元组类型可以确切的标记出有多少个元素,以及每个元素的类型;
(2)这个例子中有两个元素,每个元素的类型都是number
TS类型推论(类型推断机制):
在TS中,有些没有明确指出类型的地方,TS的类型推论机制会帮助提供类型;所以说,由于类型推论的存在,这些地方的类型注解可以省略不写。
发生类型推论的2中常见场景:
(1)声明变量并初始化时
let age = 18
// 声明变量并且立即初始化值,此时,可以省略类型注解
let a: number
a = 15
// 注意,如果声明变量但是没有立即初始化,此时,还需要手动添加类型注解
(2)决定函数返回值时
// 这种情况下 类型注解也可以不写
function add(num1: number, num2: number) {
return num1 + num2
}
类型断言:
有时候,开发人员会比TS更加明确一个值的类型,此时就可以使用类型断言来指定具体的内容
比如:
<a href="http://www.baidu.com" id="link">百度</a>
const aLink = document.getElementById("link")
// 此时鼠标放在上面会显示 const aLink: HTMLElement
getElementById 方法返回值的类型是HTMLElement,该类型只包含所有标签的公共的属性或方法,不包含a标签特有的href属性。
因此,这个类型太宽泛(不具体),无法操作href等a标签特有的属性或方法。
这种情况下就需要使用类型断言来指定更加具体的类型
使用类型断言:
const aLink = document.getElementById("link") as HTMLAchorElement
// 鼠标放上去就是const aLink: HTMLAchorElement
(1)使用as关键字实现类型断言
(2)关键字as后面的类型是一个更加具体的类型
(3)通过类型断言,aLink的乐行变的更加具体,这样就可以访问a链接特有的属性或方法了
还有另一种写法(不推荐):
const aLink = <HTMLAnchorElement>document.getElementById("link")
要怎么知道某个标签的类型呢:
在浏览器的控制台,console.dir($0)打印dom元素,在属性列表的最后面,就可看到该元素的类型,其中$0是选中的某个元素后面会出现
字面量类型:
下面两个变量的类型是不同的:
let str1 = "Hello TS" // string
const str2 = "Hello TS" // "Hello TS"
解释:
(1)str1是一个变量(let),它的值可以是任意字符串,所以类型为string
(2)str2是一个常量(const),它的值不能变只能是"Hello TS"
此处的"Hello TS",就是一个字面量类型,也就是说某个特定的字符串也可以作为TS中的类型,除字符串外,任意的JS字面量(比如对象,数字等)都可以作为类型使用
let str1 = "Hello TS"
const str2: "Hello TS" = "Hello TS" // 字符串作为类型
let age: 18 = 18 // 数字也可以作为类型
使用模式:字面量类型配合联和类型一起使用
使用场景:用来表示一组明确的可选值列表
比如:在贪吃蛇游戏中,游戏的方向的可选值是 上下左右中的任意一个
function changeDirection(direction: 'up' | 'down' | 'left' | 'right') {
console.log(direction)
}
这个的参数类型只能是up/down/left/right中的任意一个
优势:相比于string类型,使用字面量类型更加的精确和严谨
枚举类型:(数字枚举,字符串枚举)
枚举的功能类似于字面量类型+联和类型组合的功能,也可以表示一组明确的可选值
枚举:定义一组命名常量。它描述一个值,该值可以使这些命名常量中的一个
enum Direction {Up, Down, Left, Right}
function changeDirection(direction: Direction) {
console.log(direction)
}
// 访问
changeDirection(Direction.Up)
(1)使用enum关键字定义枚举
(2)约定枚举名称,枚举中的值以大写字母开头
(3)枚举中的多个值之间通过,(逗号)分隔
(4)定义好枚举后,直接使用枚举名称作为类型注解
把枚举成员作为了函数的实参,它的值是什么?
把鼠标放在上面会显示一个数字,所以,枚举成员是有值的,默认值是:从0开始自增的数值,也称为数字枚举
当然,也可以个枚举中的成员初始化值:
// Up => 10,Down => 11,Left => 12,Right => 13
enum Direction {Up = 10, Down, Left, Right}
// 也可以每个指定
enum Direction {Up = 2, Down = 5, Left = 12, Right = 1}
字符串枚举:
enum Direction1 {
Up = 'UP',
Down = 'DOWN',
Left = 'LEFT',
Right = 'RIGHT'
}
字符串枚举没有自增长的行为,因此,字符串枚举的每个成员都必须有初始值
枚举原理:
枚举是TS中为数不多的非JavaScript类型级扩展(不仅仅是类型)的特性之一。
因为:其他类型仅仅被当做类型,而枚举不仅用作类型,还提供值(枚举成员都是有值的),也就是说,其他类型会在编译为js代码的时候自动清除,但是,枚举类型会被编译为js代码
enum Direction1 {
Up = 'UP',
Down = 'DOWN',
Left = 'LEFT',
Right = 'RIGHT'
}
// 会被编译成如下的js代码
var Direction;
(function (Direction) {
Direction['Up'] = 'UP'
Direction['Down'] = 'DOWN'
Direction['Left'] = 'LEFT'
Direction['Right'] = 'RIGHT'
})(Direction || Direction = {})
枚举与前面说的字面量类型+联和类型组合的功能类似,都用来表示一组明确的可选值列表;
一般情况下,推荐使用字面量类型+联和类型组合的方式,因为相比枚举,这种方式更贱直观,简洁,高效。
any类型:
原则:不推荐使用any类型,这会让TypeScript变成"AnyScript"(失去TS类型保护的优势)
因为当值的类型为any时,可以对该值进行任意操作,并且不会有代码提示。
比如:下面这个代码,即使有错,也不会有任何的类型提示
let abi = {x: 0}
obj.bar = 100
obj()
const n: number = obj
所以说:(1)尽可能避免使用any类型,除非临时使用any来“避免”书写很长,很复杂的类型
(2)其他隐式具有any的情况:
① 声明变量不提供类型也不提供默认值
② 函数参数不加类型
(3)因为不推荐使用any,所以,这两种情况都应该提供类型
TS中的typeof操作符:
众所周知,JS提供了typeof操作符,用来在JS中获取数据的类型
实际上,TS也提供了typeof操作符:可以在类型上下文中引用变量或属性的类型(类型查询)
使用场景:根据已有变量的值,获取该值的类型,来简化类型书写
let p = {x: 1, y: 3}
function formatPoint (point: typeof p) {}
formatPoint({x: 1, y: 6})
(1)使用typeof操作符来获取变量p的类型,结果与第一种(对象字面量形式的类型)相同
(2)typeof出现在类型注解的位置(参数名称的冒号后面)所处的环境就在类型上下文(区别于JS代码)
(3)typeof只能用来查询变量或变量属性的类型,无法查询其他形式的类型