Skip to content

TypeScript学习:TS 基础学习笔记

2-1 TS具备的优势

  1. 编译时静态类型检测:函数或方法传参或变量赋值不匹配时,会出现编译错误提示,规避风险
  2. 自动提示更清晰明确
  3. 引入了泛型和一系列的TS特有特性
  4. 强大的 d.ts 生命文件:类似书目录,清晰直观展示了依赖库文件的接口、type类型、类、函数、变量等声明
  5. 轻松编译成JS文件,即使TS文件有错误,绝大多数情况也能编译出JS文件
  6. 灵活性高:尽管TS是一门强类型检查语言,但也提供了 any类型as any断言,这也使得TS具备一定灵活性(虽然不建议)

2-2 - 2-8 常用的24种TS类型

基本类型

  • number
  • string
  • boolean
  • null
  • undefined
  • symbol

根类型

  • Object
  • {}

对象类型

  • array
  • object
  • function

枚举

  • enum

其他特殊类型

  • any
  • unknown
  • never
  • void
  • tuple 元组
  • 可变元组

合成类型

  • 联合类型
  • 交叉类型

字面量数据类型

2-9 枚举

为什么使用枚举

常量带来的局限性。方法参数不能定义为具体类型,之能初级使用 number、string 基本类型替代,降低了代码的可读性和可维护性

枚举带来的好处

  1. 有默认值和可以自增值,节省编码时间
  2. 语义更清晰,可读性增强:枚举是一种值类型的数据类型,方法参数可以明确参数类型为枚举类型

2-10 枚举的定义、取值和分类

数字枚举

ts
enum Week {
	Monday = 1,
	Tuesday,
	Wendsday,
	Thrisday,
	Friday,
	Sarturday,
	Sunday,
}
// 具备双重映射
console.log('monday', Week.Monday) // 1
console.log('monday', Week['Monday']) // 1

console.log('monday', Week[1]) // Monday
console.log('monday', Week[5]) // Friday

字符串枚举

单独映射,由 key 到 value

ts
enum WeekEnd {
	Monday = '星期一',
	Tuesday = '星期二',
	Wendsday = '星期三',
	Thrisday = '星期四',
	Friday = '星期五',
	Sarturday = '星期六',
	Sunday = '星期日',
}

console.log('WeekEnd', WeekEnd.Friday) // 星期五
console.log('WeekEnd', WeekEnd['星期三']) // undefined
console.log('WeekEnd', WeekEnd[1]) // undefined

2-11 解析枚举底层

2-13 any, unknown 的两点区别和应用场景

相同点:anyunknown可以是任何类的父类,所以任何类型的变量都可以赋值给 any 类型或 unknown 类型的变量`

不同点:

  • any 也可以是任何类的子类,但unknown不行,所以any类型的变量都可以赋值给其他类型的变量
  • 不能拿unknown类型的变量来获取任何属性和方法,但any类型的变量可以获取任意名称的属性和任意名称的方法

2-14 interface

接口:令一种定义对伊类型的类型。具有继承的特点,所以使用频率高于type

接口的应用场景

  • 一些第三方包或者框架底层源码中有大量的接口类型
  • 提供方法的对象类型的参数时使用
  • 为多个同类别的类提供统一的方法和属性声明

如何定义接口 interface Xxx {}

继承接口 interface A extends B {}

新的接口只是在原来接口继承之上增加了一些属性或方法,这时就用接口继承 interface A inplements B

2-15 可索引签名

ts
interface Product {
	name: string
	price: number
	account: number
	[x: string]: any // 下面用 Symbol 和 数字作为key 也是可以的
}

let p: Product = {
	name: 'xx',
	price: 100,
	account: 20,
	[Symbol('like')]: false,
	100: 'hahah',
}

2-16 索引类型访问 + 更多理解

ts
const symId = Symbol('001')
interface Product {
  [symId]: number | string
  name: string
  price: number
  account: number
  buy(): void
}

type A = Product(typeof symId)

例:获取接口里所有的属性名的类型

ts
type Pkeys = keyof Product // "name"|"price"||"account"|"buy"|"typeof symId"
// 当一个值以字面量形式充当类型时,它的值就是它本身

type AllKeys<T> = T extends any ? T : never
type Pkeys2 = Allkeys<keyof Product>

2-17 说说对 void 的理解

2-18 null 和 undefined 相关细节

2-19 TS 函数和 TS 函数类型,rest 参数

2-23 interface 和 type 区别

type和接口类似,都用来定义类型,但typeinterface区别如下:

  1. 定义类型和范围不同
  • interface 只能定义对象类型或接口当名字的函数类型
  • type 可以定义任何类型,包括基础类型、联合类型、交叉类型和元组
  1. 接口可以extends一个或者多个接口或类,也可以继承type,但type类型没有继承功能。但一般接口继承类和type的应用场景很少见

  2. type交叉类型&可让类型中的成员合并成一个新的type类型,但接口不能交叉合并

  3. 接口可合并声明

2-24 元组 Tuple

满足以下 3 点的数组就是元组

  1. 在定义时每个元素的类型都确定
  2. 元素值的数据类型必须是当前元素定义的类型
  3. 元素值的个数必须和定义时个数相同

2-25 TS 数组和数组元素怎样同时为只读

ts
const account = [10, 20, 30]
// acount = [10, 20, 30, 40] 数组不可修改
account[0] = 100 // 但数组中的元素可被改变

const account2 = ['a', 'b', 'c'] as const
// account[1] = 2 不可改变,会报错

2-26 可变元组及运用场景

ts
let payment: [string, number, number] = ['$', '10', '20']

// 可变元组:具备元组固定值又具有数组灵活性特点
let customers: [string, number, number, ...any[]] = ['$', '10', '20', '30', '40']

2-27 可变元组标签(tag)

ts
// 可变元组解构
let [name, age, address, ...rest]: [name_: string, age: number, address: string, ...rest_: any[]] =
	['fri', 24, '成都', 'hello world']

2-28 类、静态属性

定义:类就是拥有相同属性和方法的一系列对象的集合

展开理解:类是一个模具,是从该类包含的所有具体对象中抽象出来的一个概念,类定义了它所包含的全体对象的静态特征和动态特征

2-29 何时用到静态成员

静态成员:静态属性+静态方法

ts
class DateUtil {
	static formatDate() {}
	static getHours() {}
	static getMinutes() {}
	static getSeconds() {}
}

// DateUtil.formatDate() 这样来调用

2-30 TS 单例设计模式的实现

单例:一个类只允许外部获取到它的唯一的实例对象

立即创建单例模式 - 缺点是运行后直接就创建单例了

ts
class DateUtil {
	static dateUtil = new DateUtil()
	private constructor() {}
	formatDate() {}
	getHours() {}
	getMinutes() {}
	getSeconds() {}
}

const dateUtil1 = DateUtil.dateUtil
const dateUtil2 = DateUtil.dateUtil
console.log(dateUtil1 === dateUtil2) // true
dateUtil1.formatDate()

const dateUtil = DateUtil.dateUtil
export default dateUtil

用到时再创建,性能好,但写法更麻烦些

ts
class DateUtil {
	static dateUtil: DateUtil
	static getInstance() {
		if (this.dateUtil) {
			this.dateUtil = new DateUtil()
		}
		return this.dateUtil
	}
	private constructor() {}
	formatDate() {}
	getHours() {}
	getMinutes() {}
	getSeconds() {}
}

const dateUtil1 = DateUtil.getInstance()
const dateUtil2 = DateUtil.getInstance()

console.log(dateUtil1 === dateUtil2) // true
dateUtil1.formatDate()

const dateUtil = DateUtil.getInstance()
export default dateUtil

共 20 个模块,1301 篇 Markdown 文档。