TypeScript是js的超集,ts提供了js的所有功能,并且额外的增加了: 类型系统
typescript类型系统的主要优势: 可以显示表基础代码中的意外行为,从而降低了发生错误的可能性
示例代码:
let age: number = 18
说明: 代码中的 ' : number '就是类型注解
作用: 为变量添加类型约束,比如,上述代码中,约定变量 age 的类型为 number(数值类型)
解释: 约定了什么类型,就只能给变量赋值改类型的值,否则就会报错
可以将ts中的常用基础类型细分为两类:
原始类型: number/string/boolean/null/undefined/symbol
特点: 简单,这些类型完全按照js中类型的名称来书写
let age: number = 18
let myName: string = 'zs'
let isLoading: boolean = false
对象类型: object(包括,数组, 对象, 函数等)
特点: 对象类型,再ts中更加细化,每个具体的对象都有自己的类型语法
let number: number[] = [1, 3, 5]
let string: Array = ['a', 'b', 'c']
需求: 数组中既有number类型,又有string类型,可以用如下的方式
let arr: (number | string)[] = [1, 'a', 3, 'b']
解释: ' | '在ts中叫做联合类型(由两个或对各其他类型组成的类型,表示可以是这些类型中的任意一种)
注意: 这是ts中的联合类型的语法,只有一根竖线,需要与js中的或( || )进行区分
类型别名(自定义类型): 为任意类型起别名
使用场景: 当同一类型(复杂)被多次使用是,可以通过类型别名,简化该类型的使用
type CustomArray = (number | string)[]
let arr1: CustomArray = [1, 'a', 3, 'b']
let arr2: CustomArray = ['x', 'y', 6, 7]
解释:
函数的类型实际上指的是: 函数参数和返回值的类型
为函数指定类型的两种方式:
function add(num1: number, num2: number): number {
return num1 + num2
}
const add = (num1: number, num2: number): number => {
return num1 + num2
}
const add: (num1: number num2: number) => number = (num1, num2) => {
return num1 + num2
}
解释: 当函数作为表达式时,可以通过类似箭头函数形式的语法来为函数添加类型
注意: 这种形式只适用于函数表达式
如果函数没有返回值,那么函数的返回值类型为: void
function great(name: string): void {
console.log('Hello', name)
}
void是一个特殊的函数返回值类型
使用函数实现某个功能时,参数可以传也可以不传,这种情况下,在给函数参数指定类型时,就用到可选参数了
比如,数组的slice()方法,可以slice()也可以slice(1),还可以slice(1, 3)
function mySlice(start?: number, end?: number): void {
console.log('起始索引: ', start, '结束索引: ', end)
}
在进行打印的时候,未填的可选参数展示undefined
可选参数: 可传可不穿的参数名称跟后面添加 ' ? '(问号)
注意: 可选参数只能出现在参数列表的最后,也就是说可选参数后面不能再出现必选参数
js中的对象是由属性和方法构成的,而ts中对象的类型就是在描述对象的结构(有什么类型的属性和方法)
对象类型的写法:
let person: { name: string; age: number; sayHi(): void; greet(name: string): void } = {
name: 'zs',
age: 18,
sayHi() {},
greet(name) {}
}
解释:
直接使用 {} 来描述对象结构,属性采用属性名: 类型的形式;方法采用方法名(): 返回值类型的形式
如果方法有参数,九在方法名后面的小括号中指定参数类型(比如: greet(name: string): void)
在一行代码中指定对象的多个属性类型时,使用 ' ; ' (分号)来分隔
let person: {
name: string
age: number
// sayHi(): void
sayHi: () => void
greet(name: string): void
} = {
name: 'zs',
age: 18,
sayHi() {},
greet(name) {}
}
对象的属性或方法,也是可选的
比如,在使用axios({...})时,如果发送GET请求,method属性就可以省略
function myAxios(config: { url: string; method?: string }) {
console.log(config)
}
可选属性的语法与函数可选参数的语法一致,都使用 ' ? '(问号)来表示
当一个对象类型被多次使用时,一般会使用接口来描述对象的类型,达到复用的目的
// let person: { name: string; age: number; sayHi(): void } = {
// name: 'zs',
// age: 18,
// sayHi() {}
// }
// let person1: { name: string; age: number; sayHi(): void }
interface IPerson {
name: string
age: number
sayHi(): void
}
let person2: IPerson = {
name: 'zs',
age: 18,
sayHi() {}
}
解释:
interface(接口)和type(类型别名)的对比:
// 接口
interface IPerson {
name: string,
age: number,
sayHi(): void
}
// 类型别名
type IPerson = {
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 }
解释:
interface Point2D { x: number; y: number }
// 使用 继承 实现复用
interface Point3D extends Point2D { z: number }
let p3: Point3D = {
x: 1,
y: 0,
z: 2
}
场景: 在地图中,使用经纬度坐标来标记位置信息
可以使用数组来记录坐标,那么,该数组中只有两个元素,并且这两个元素都是数值类型
let position: number[] = [39.5427, 116.2317]
使用 number[] 的缺点: 不严谨,因为改类型的数组中可以出现任意多个数字
更好的方式: 元组(Tuple)
元组类型时另一种类型的数组,他确切的知道包含多少个元素,以及特定索引对应的类型
let position: [number, number] = [39.5427, 116.2317]
解释:
在TS中,某些没有明确指出类型的地方,TS的类型推论机制会帮助提供类型
发生类型推论的2中常见场景:
// 注意: 如果声明变量但是没有立即初始化值 即赋值 必须手动添加类型注解
let age = 18
function add(num1: number, num2: number) {
return num1 + num2
}
注意: 这两种情况下,类型注解可以省略不写
推荐: 能省略类型注解的地方就省略,提升开发效率,建议参数添加上类型注解
技巧: 如果不知道类型,可以通过鼠标放在变量名上,通过编译器提示查看类型
有时候开发者比ts更明确一个值的类型,此时可以使用类型断言来指定更具体的类型
比如
传智教育
注意: getElementById 方法返回值的类型时 HTMLElement,改类型只包含所有标签公共的属性或方法,不包含 a 标签特有的 href 等属性
因此,这个类型太宽泛(不具体),无法操作 href 等 a 标签特有的属性或方法
解决方法: 这种情况下就需要使用类型断言指定更加具体的类型
使用类型断言:
const aLink = document.getElementById('link') as HTMLAnchorElement
解释:
另一种语法,使用 <> 语法,这种语法形式不常用:
const aLink = document.getElementById('link')
技巧: 在浏览器控制台,通过 console.dir() 打印 DOM 元素,在属性列表的最后面,即可看到该元素的类型
在浏览器中选中一个元素,标签后面显示 $0
去到控制台,输入
console.dir($0)
展开后在最底部即可看到元素类型
let str1 = 'Hello TS'
const str2 = 'Hello TS'
通过TS类型推论机制,就可以得到答案: