3.7 对象类型
JS中的对象是由属性和方法构成的,而TS中对象的类型就是在描述对象的结构(有什么类型的属性和方法)。
对象类型的写法:
let person: {
name: string; age: number; sayHi(): void } = {
name: 'jack',
age: 19,
sayHi() {
}
}
解释:
- 直接使用{}来描述对象的结构。属性采用属性名:类型的形式;方法采用方法名():返回值类型的形式。
- 如果方法有参数,就在方法名后面的小括号中指定参数类型(比如:greet(name: string):void)。
- 在一行代码中指定对象的多个属性类型时,使用 ; (分号) 来分隔。
- 如果一行代码只指定一个属性类型(通过换行来分隔多个属性类型),可以去掉 ;(分号) 。
- 方法的类型也可以使用箭头函数形式(比如:{sayHi:()=> void})。
对象的属性或方法,也可以是可选的,此时就用到可选属性了。
比如,我们在使用axios({ … })时,如果发送GET请求,method属性就可以省略。
function myAxios(config: {
url: string; method?: string }) {
console.log(config)
}
可选属性的语法与函数可选参数的语法一致,都使用 ? (问号) 来表示。
3.8 接口
interface(接口)和type(类型别名)的对比:
-
相同点:都可以给对象指定类型。
-
不同点:
- 接口,只能为对象指定类型。
- 类型别名:不仅可以为对象指定类型,实际上可以为任意类型指定别名。
interface IPerson {
//interface接口声明时,无等号
name: string
age: number
sayHi(): void
}
type IPerson = {
//type类型别名声明时,有等号
name: string
age: number
sayHi(): void
}
type NumStr = number | string
// 类型别名:不仅可以为对象指定类型,实际上可以为任意类型指定别名。
接口的继承
如果两个接口之间有相同的属性或方法,可以将公共的属性或方法抽离出来,通过继承来实现复用。
比如,这两个接口都有x,y两个属性,重复写两次,可以,但很繁琐。
interface Point2D {
x: number; y: number }
interface Point3D {
x: number; y: number; z: number }
更好的方式:
interface Point2D {
x: number; y: number }
interface Point3D extends Point2D {
z: number }
解释:
- 使用extends(继承)关键字实现了接口Point3D继承Point2D。。
- 继承后,Point3D就有了Point2D的所有属性和方法(此时,Point3D同时有x,y,z三个属性)。
3.9 元组(Tuple)
3.10 类型推论
在TS中,某些没有明确指出类型的地方,TS的类型推论机制会帮助提供类型。
换句话说,由于类型推论的存在,这些地方,类型注解可以省略不写!
发生类型推论的两种常见场景:
1 声明变量并初始化时
let age = 18 // 鼠标移入变量名称age,TS自动推断出变量age为number类型
2 决定函数返回值时。
如图:省略了add()函数返回值类型(:number)
鼠标移入函数add()时,TS自动根据num1和num2两个变量的类型推断出返回值的类型是number。
注意:这两种情况下,类型注解可以省略不写
推荐:能省略类型注解的地方就省略(充分利用TS类型推论的能力,提升开发效率)。
技巧:如果不知道类型,可以通过鼠标放在变量名称上,利用VSCode的提示来查看类型。
3.11 类型断言
有时候你会比TS更加明确一个值的类型,此时,可以使用类型断言来指定更具体的类型。
比如,
注意:getElementById方法返回值的类型是HTMLElement,该类型只包含所有标签公共的属性或方法,不包含a标签特有的href等属性。
因此,这个类型太宽泛(不具体),无法操作href等a标签特有的属性或方法。
解决方式:这种情况下就需要使用类型断言指定更加具体的类型。
使用类型断言
解释:
- 使用 as 关键字实现类型断言。
- 关键字 as 后面的类型是一个更加具体的类型(HTMLAnchorElement是HTMLElement的子类型)
- HTMLAnchorElement是a标签对应的dom元素类型,因此通过类型断言,aLink的类型变得更加具体,这样就可以访问a标签特有的属性或方法了(比如href属性)。
另一种语法,使用<>语法,这种语法形式不常用知道即可:
const aLink = <HTMLAnchorElement>document.getElementById('link')
技巧:console.dir()
在浏览器控制台,通过console.dir()打印DOM元素,在属性列表的最后面,即可看到该元素的类型。
提示:打开控制台后ctrl+shift+c选取DOM元素,然后再输入console.dir($0)并回车,在属性列表的最后可以看见该DOM元素对应的类型。
a标签:HTMLAnchorElement
span标签:HTMLSpanElement
div标签:HTMLDivElement
button标签:HTMLButtonElement
等等…
3.12 字面量类型
以下两个变量的类型分别是什么?
let str1 = 'Hello TS'
const str2 = 'Hello TS'
通过TS类型推论得出:
- 变量str1的类型为:string
- 变量str2的类型为:‘Hello TS’
解释:
- str1 是一个变量(let声明变量),它的值可以是任意字符串,所以类型是:string
- str2 是一个常量 (const声明常量),它的值不能变化只能是‘Hello TS’,所以,它的类型为:‘Hello TS’。
注意:此处的**‘Hello TS’,就是一个字面量类型**。也就是说某个特定的字符串也可以作为TS中的类型。
除字符串外,任意的JS字面量(比如,对象,数字等)都可以作为类型使用。
let age: 18 = 18 //let age: 18 = 19报错:不能把类型19分配给类型18
// 这里的变量age的类型就是数字18
字面量类型的使用场景
使用模式:字面量类型配合联合类型一起使用。
使用场景:用来表示一组明确的可选值列表。
比如,在贪吃蛇游戏中,游戏的方向的可选值只能是上,下,左,右的任意一个。
function changeDirection(direction: 'up' | 'down' | 'left' | 'right') {
console.log(direction)
}
解释:参数direction的值只能是up/down/left/right中的任意一个。
优势:相比于string类型,使用字面量类型更加精确,严谨。
~~
~~
下一章节:4.TypeScript入门之TS常用类型(3)