TypeScript和JavaScript都有的类型

字符串(string)

1
2
3
4
5
// 定义一个变量并指定类型
let str1: string

// 定义一个变量指定类型并且设置初始值
let str2: string = '字符串类型'

数值(number)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 定义一个变量并指定类型
let num1: number

// 定义一个变量指定类型并且设置初始值
let num2: number = 10

// 二进制的写法
let num3: number = 0b110

// 八进制
let num4: number = 0o555

// 十六进制
let num5: number = 0xf23

布尔值(boolean)

1
2
3
4
5
6
7
8
// 定义一个变量并指定类型
let bool1: boolean

// 定义一个变量指定类型并且设置初始值
let bool2: boolean = true

// 也可以写成表达式
bool1 = 20 > 30

数组(Array)

1
2
3
4
5
6
// 定义数组需要确定数组中存放的类型是什么元素, 最好存放的数据类型是固定的
// 使用类型注解, 不推荐. 因为在react jsx中是会有冲突
let arr: Array<string> = []

// 推荐的写法
let arr1: string[] = []

对象(object)

1
2
3
4
5
// 这样定义的对象通过obj.name是获取不到数据的, 建议不指定让ts自动推导出类型
let obj: object = {
name: '来福',
age: 3
}

null

1
let nl: null = null

undefined

1
let un: undefined = undefined

symbol

1
2
3
4
5
6
let title1 = Symbol('title')
let title2 = Symbol('title')
let sy: symbol = {
[title1]: '前端',
[title2]: '后端'
}

TypeScript中特有的类型

any

在某些情况下无法确定一个变量的类型, 并且可能会发生变化,这时可以使用any类型,设置了any相当于关闭了TS对该变量的类型检测, any类型可以进行任何操作, 也可以赋任何的值, 可以用来进行一些类型断言

1
2
3
4
5
let every: any = 'Holle word'
// 可以修改为任意类型
every = 123
every = true
every = {}

unknown

未知类型实际上就是一个类型安全的any,unknown类型的变量不能直接赋值给其他变量只能赋值给any和unknown类型

1
let uk: unknown

void

void类型像是与any类型相反,它表示没有任何类型,表示为空, 可以不写

1
2
3
4
// 函数为例,表示没有返回值的函数
function fn(): void {
return
}

never

never类型表示的是那些永不存在的值的类型,总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型

1
2
3
4
5
// 表示永远不会返回一个值
function fn1(): never {
throw new Error('报错了')
}

tuple

1
2
// 元祖可以明确数组中的类型
let tuple: [string, number, string] = ['常威', 15, '在打来福']

字面量

1
2
3
4
5
6
7
8
// 文本也是可以作为类型的, 叫字面量类型
const str: '常威在打来福' = '常威在打来福'

// 字面量类型的意义就是必须结合联合类型使用
type Align = 'left' | 'right' | 'center'
let align: Align = 'left'
align = 'right'
align = 'center'

字面量推理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const info = {
url: 'http://xxx.com/src',
method: 'GET'
}

// 方法二
//const info = {
// url: 'http://xxx.com/src',
// method: 'GET'
//} as const

function request(url: string, method: 'GET' | 'POST') {
console.log(url, method)
}
// 方法一
request(info.url, info.method as 'GET')

函数参数添加类型

1
2
3
4
5
6
// 函数变量添加类型,并指定返回值的类型
function sum(num1: number, num2: number): number {
return num1 + num2
}

let result = sum(123, 456)

对象类型

1
2
3
4
5
6
function fn(obj: { a: number, b: number }) {
console.log(obj.a)
console.log(obj.b)
}

fn({ a: 123, b: 456 })

联合类型

1
let id: number|string|boolean

可选类型

当参数是可选类型的时候,类似于这个参数是 ‘类型|undefined’ 的联合类型, 当有多个类型的时候可选类型必须放在必选类型的后面

1
2
3
4
5
6
7
function fn(obj: { b:string, a?: number }) {
console.log(obj.a)
}

fn('常威')
fn('常威', undefined)
fn('常威', 18)

只声明不指定类型

只声明变量不指定类型,则TS解析器会自动判断变量为any类型 any类型的值可以复制给任意变量

1
let ev

类型别名

1
2
3
4
5
6
7
8
9
type IdType = string|number|boolean
type ObjType = {
x: number
b: number
c: string
}

function fnId(id: IdType) {}
function fnObj(obj: ObjType) {}

类型断言

类型断言 可以用来告诉解析器变量的类型

1
2
3
let str: string
str = str1 as string
str = <string>str1

非空类型断言

1
2
3
function fn(name?: string) {
console.log(name!.length)
}

类型判断

1
2
3
4
let str1: string
if (typeof str2 === 'string') {
str1 = str2
}

可选链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type Person = {
name: string
friend?: {
name: string
age?: number
}
}

const info: Person = {
name: '常威',
friend: {
name: '来福'
}
}

console.log(info.name)
console.log(info.friend?.name) // 可选链
console.log(info.friend?.age) // 可选链

!!

1
2
3
const name: string = '常威'

const flag: boolean = !!name // 可转为Boolean类型

??

空值合并操作符, 当操作符左侧是null或者undefined, 返回右侧的值, 否则返回左侧的值

1
2
const str: string|null = null
const str1 = str ?? '常威在打来福'

类型缩小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// 1. typeof 的类型缩小
type IDType = number | string
function printID(id: IDType) {
if (typeof id === 'string') {
console.log(id.toUpperCase())
} else {
console.log(id)
}
}

// 2.平等类型缩小(===, ==, !==, !=, switch)
type Dir = 'left' | 'right' | 'top' | 'bottom' | center
function printDir(dir: Dir) {
//if判断
//if (dir === 'left') {
//console.log(dir)
//} else if () {}

// switch判断
switch (dir) {
case 'left':
console.log(dir)
break
case: ...
}
}

// 3.instanceof
function printTime(tiem: string | Date) {
if (time instanceof Date) {
console.log(time.toUTCString())
} else {
console.log(time)
}
}

// 4. in
type Chicken = {
rap: () => void
}

type IKun = {
basketball: () => void
}

function sing(ikun: Chicken | IKun) {
if ('rap' in ikun) {
ikun.rap()
} else {
ikun.basketball()
}
}

const chicken: Chicken = {
rap() {
console.log('rap')
}
}

sing(chicken)

函数的类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 1.函数作为参数, 在参数中的类型
function rap() {}
type RapFnType = () => void
function sing(fn: RapFnType) {
fn()
}
sing(rap)

// 2.定义常量时函数的类型
type JumpFnType = (n1: number, n2: number) => number
const jump: JumpFnType = (a1: number, a2:number) => {
return a1 + a2
}

const jump2: (n1: number, n2: number) => number = (a1: number, a2:number) => {
return a1 + a2
}

函数重载

函数名称相同, 单参数不同的几个函数, 就是函数的重载; 在函数的重载中, 实现函数是不能直接被调用的

1
2
3
4
5
6
7
8
function add(n1: number, n2: number): number
function add(n1: string, n2: string): string

function add(n1: any, n2: any): any {
return n1 + n2
}
const res = add(10, 20)
const res2 = add('常威', '再打来福')