-
1.TypeScript\
-
为什么需要TS?\
- TS提供了一套静态检测机制, 可以帮助我们在编译时就发现错误\
-
TS由什么组成?\
- ECMAScipt、DOM、BOM\
-
基本操作:\
-
ts:\
- 生成配置文件:tsc -init\
- 编译:tsc\
- 动态编译:tsc index.ts --watch\
- 创建文件: echo ''>index.ts\
-
ts-node:\
- 编译并执行,不生成js文件:ts-node index.ts\
-
-
1.基础类型、任意类型(TS最主要的特点就是可以定义静态类型)\
- 一旦定义就不可改变(例子:let count: number = 1,count不可改变,而且可以用number类型的所有方法)\
-
基础静态类型(Boolean、Number、String、Null、Undefined、Symbol、Bigint)\
- Number可以包含:NaN、普通数字、无穷大infinity、十进制、十六进制\
-
void概念:(函数没有return返回值的时候用)\
- 空值,接收undefined和null\
- void和undefined的区别:void不能赋值给别人,undefined可以\
- 写在函数上,函数不能return\
- any和unknown的区别:unknown比any更加安全\
-
对象静态类型(Object、[Array、tuple]、Class、Function、Enum、Any、Unknown、never)\
-
unknown\
- 不能去调用属性和方法\
- 不能当作子类型赋值给别人,要赋值只能赋值给unknown或any\
- object对象类型、array数组类型、class类类型、function函数类型\
- enum枚举、any任何、unknown未知\
-
tuple元组:\
- 概念:定义具有有限数量的未命名属性的类型\
- 特性:可以限制数组元素的个数和类型,它特别适合用来实现多值返回。\
- never概念:如果异常或死循环,程序被中断了,没有返回值,就在函数后写:never\
-
- const fn: () => string,意思是定义的时候必须是一个函数,并且有返回值是string\
- 类型注解annotation(给它标注let count: number)\
- 类型推断inference(自己推断)\
- 返回参数和返回类型的注解:function getNumber({ one, two }: { one: number; two: number }){}\
- 数组类型注解:const numberArr: number[] = [1, 2, 3];\
-
3.接口Interface(定义数据类型)和对象类型\
-
接口Interface\
- 定义数据类型,如果重名两个接口会合并定义\
- 它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)。可用于[对类的一部分行为进行抽象]以外,也常用于对「对象的形状(Shape)」进行描述\
- 可选式操作符?属性是可选的,可以有也可以没有这个值\
- 内置变量(propName: string):any:属性名是string,属性是any。一般是any因为不知道后台返回什么\
- 联合类型|:\
- 只读属性readonly:是只读的,定义后不能再赋值了\
- 对象类型\
-
-
4.数组类型\
- 数组定义::number、:string、:boolean、:any(常用)\
- 数组泛型定义:: Array、: Array、: Array\
- 多维数组定义:let arr: number[][][] = [[[]], [[]], [[]]];\
- 多维数组泛型定义:let arr: Array<Array> = [[], [], []];\
- 类数组arguments:let arr: IArguments = arguments;\
-
5.函数类型(函数重载)\
- 函数定义:function (name: string, age?: number): string\
-
接口Interface约束类型:\
- interface User {name: string;age?: number;}\
- function (user: User): User { return user }\
-
函数重载(重点)\
- 概念:重载是方法名字相同,但参数不同,返回类型可以相同也可以不同。如果参数类型不同,则操作函数参数类型应设置为any。参数数量不同你可以将不同的参数设置位可选。\
- function fn(params: number): void;(重载函数-规则)\
- function fn(params: string, params2: number): void;(重载函数-规则)\
- function fn(params: any, params2?: any): any {return params;}(执行函数-逻辑)\
-
6.类型断言 | 联合类型 | 交叉类型\
-
类型断言( as或A> )\
- 第一种方法:(num as string).length\
- 第二种方法:(A>type).run\
- 只是欺骗ts,不能避免运行错误,不能滥用断言。\
-
临时断言:\
- (window as any).abc = 123;\
- any可以被断言成任何类型\
- return type as boolean;会欺骗TS,不能乱用\
-
联合类型( | )\
- let phone: number | string = 18598252994;\
- 声明函数使用:let fn = function (type: number | boolean): boolean {return !!type;};\
- 注释:!!是强制转布尔值\
-
交叉类型( & )\
- interface Pople {name: string;age: number;}\
- interface Man {sex: number;}\
- const czy = (man: Pople & Man): void => {console.log();};\
-
-
7.内置对象(Promise对象)\
-
ECMAScipt的内置对象\
- 正则表达式(regular expression):const regexp: RegExp = /\w\d\s/;\
- 日期(Date ):const date: Date = new Date();\
- 错误(Error):const error: Error = new Error("错误");\
-
DOM的内置对象\
-
节点列表(NodeList )\
- const list: NodeList = document.querySelectorAll("#list li");\
- 和arguments不一样,打印出来是类数组有forEach、item、keys、values方法\
-
HTML元素(HTMLElement)\
- const body: HTMLElement = document.body;\
-
Div元素(HTMLDivElement)\
- const div: HTMLDivElement = document.querySelector("div");\
-
-
BOM的内置对象\
-
鼠标事件(MouseEvent)\
- document.addEventListener("click", (e: MouseEvent) => {console.log(e);});\
-
-
Promise对象(Promise)\
- function promise(): Promise {return new Promise((resolve, reject) => {resolve(1);});}\
-
-
8.1.Class 类类型\
-
定义类\
- class ClassName{ name:string; constructor(name:string){this.name=name} }\
-
类的修饰符\
- public(共用变量)内部和外部都能访问\
- private(私有的)私有变量只能在内部访问\
- protected(受保护的)内部和子类中能访问\
-
静态属性\
- static(静态属性)自定义属性,不需要new,通过类名ClassName访问\
-
静态函数\
- static run(): string {return "run()"; }\
- 静态函数只能访问static静态属性(因为静态函数的this指的是当前这个类,而构造函数里面的this指的是新的实例对象)\
- 静态函数和内部变量双向不能调用。只能ClassName.run()\
-
interface接口(约束Class)\
- interface Person {run(type: boolean): boolean;}\
- interface H {set(): void;}\
- class Man implements Person, H {run(type: boolean): boolean {return type; }set() {}}\
-
继承extends\
- super可以让子调用父的属性和方法\
- 子类调用父类,必须调用父类的constructor,用super('张三')\
-
-
8.2.抽象类(abstract)\
- abstract class A {name: string;constructor(name: string) {[this.name](this. name) = name; }abstract getName(): string;}\
- 抽象类不能被new实例化,要去派生类(class)里面实现\
-
9.元组(Tuple)\
- let arr: [string, number] = ["张三", 1];\
- 应用场景(二维数组):let excel: [string, string, number][] = [["title", "name", 1]];\
-
10.枚举类型(Enum)\
- 数组枚举enum Color {red,green,blue,}(自动从0,1,2开始增长)\
- 增长枚举enum Color {red = 3,green,blue,}(自动从3,4,5开始增长)\
- 字符串枚举enum Color {red = "red",green = "green",blue = "blue",}\
- 异构枚举enum Color {no = "no",yes = 1,}\
- 接口枚举interface A {red: Color.yes;}\
- const枚举(用了会编译成常量,不用会编译成对象)\
-
反向映射:\
- enum Types {success = 456,}\
- let suc: number = Types.success;\
- let key = Types[suc];(数字支持反射,字符串不支持反射)\
- Types[Types["success"] = 456] = "success";\
-
11.类型推断 | 类型别名\
- 类型推断let str = "张三";\
-
类型别名\
-
联合(type str = string | number;)\
- let str: str = "张三";let num: str = 123;\
-
函数(type cb = () => string;)\
- const fn: cb = () => "张三";\
- 值(type T = "off" | "on" | false | 5;)\
- let str: T = false;\
-
-
12.Never 类型\
- type bbb = string & number;\
- 出现never可能声明有问题\
- 抛出错误或无限循环函数用never\
- 在switch(type){case 'a'; break;}中 defined\
-
13.1.上集 Symbol 类型\
-
let s: symbol = Symbol();\
- 字符串或数字,不建议传对象或数组\
- 内存地址指针位置不同所以是唯一值\
- 作用:一般用于对象属性的键值\
-
和基本属性的区别:\
- for-in循环obj、Object.keys(obj)、Object.getOwnPropertyNames(obj)、JSON.stringify(obj)时,不能得到symbol键值\
- Object.getOwnPropertySymbols(obj)时,能得到symbol键值\
-
-
13.2.下集 迭代器(Symbol.iterator) | 生成器(for-of循环)\
-
迭代器(Symbol.iterator)\
- 迭代器定义在经常使用的类型prototype里,如数组、arguments(类数组)、NodeList(类数组)、new Set()、new Map()\
- 伪数组、类数组有iterator迭代器\
- 对象object是没有iterator迭代器的,可以用for-in或values\
-
生成器(for-of循环)\
- 自动调用Set下的entries方法帮我们把函数取出来\
-
和for-in循环的区别:\
- for-in循环的是索引(对象),for-of循环的是值(数组)\
-
-
🍗14.1.***函数泛型(TS中的重点)\
- Vue3是通过TS编写的,用了非常多泛型\
-
概念:\
- 把数据类型参数化\
- 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。泛型就是把不能明确的类型,变成参数,名为类型参数,一般用T来表示。类型变量,它是一种特殊的变量,只用于表示类型而不是值\
-
作用:\
- 创建可重用的组件、灵活扩展、可以在编译时发现你的类型错误\
- 手写泛型\
-
函数式泛型\
- 单类型function add(a: T, b: T): Array {return [a, b];}\
- 多类型function sub<T, U>(a: T, b: U): Array<T | U> {let arr: Array<T | U> = [a, b];return arr;}\
-
泛型约束\
-
先定义接口约束\
- interface Len {length: number;}\
-
在泛型时extends继承接口\
- function getLength(arg: T) {return arg.length;}\
-
-
🍗14.2.泛型约束(keyof) | 泛型类\
-
约束对象的key(keyof)\
- function prop<T, K extends keyof T>(obj: T, key: K) {return obj[key];}\
- 用keyof分割T,T是传过来的对象,分割成联合类型\
- 约束对象的key,避免对象的key值没有的时候TS不会提示\
-
泛型类\
- class Sub {attr: T[] = [];add(a: T): T[] {return [a]; }}\
- 实例化:let num = new Sub();\
- 实例化:let str = new Sub();\
-
-
15.tsconfig.json 配置文件\
- 编译指定的文件("include": ["./index.ts"],)执行tsc只有index.ts编译\
- 不编译指定的文件("exclude": ["./index.ts"],)执行tsc只有index.ts不编译\
- 删除注释("removeComments": true,)默认false\
-
指定编译js的版本(es5、es6)\
- ("target": "es2016", )默认es6\
- 兼容低版本配置文件("target": "es5",)变成ES5\
- 是否允许编译js文件("allowJs": true,)指引入js文件到TS中再编译\
- 编译模式("module": "commonjs",)默认commonjs,可选es6模式、amd、umd等\
- 编译代码源文件("sourceMap": true,)默认false,方便打包文件找错误\
- 严格模式("strict": true,)默认开启\
-
16.namespace 命名空间\
- TypeScript与ECMAScript 2015一样,任何包含顶级import或export的文件都被当成一个模块。相反的,如果一个文件不带有顶级的import或export声明,那么它的内容被视为全局可见的。(因此对模块也是可见的)\
-
namespace 命名空间(namespace A {export const a = 1;})\
- 会被编译成一个对象(包了一个function,是一个对象)\
-
嵌套命名空间\
- namespace A {\
- export const a = 1;\
- export namespace C {\
- export const d = 5;\
- }\
- }\
- A.C.d\
-
抽离命名空间\
- 概念:把命名空间抽离成一个文件\
- 方法:export 命名空间,在其他文件import使用\
-
简化命名空间\
- 用import关键字\
- 方法:import myA = A.C;拿到myA.d\
- 注意:不能通过ts-node运行,不认识\
-
命名空间的合并\
- 重名的命名空间会自动合并\
-
17.三斜线指令\
- 1.引入其他TS文件(///)\
-
2.声明文件(///)\
- 安装node声明文件:npm install @types/node -D\
- 声明文件一般是:@types/包名\
- 它会去找node的index.ts声明文件\
-
18.声明文件\
- axios有指定TS声明文件,可以在TS文件中引入\
-
express没有指定声明文件,会报错\
- 尝试使用
npm i --save-dev @types/express(如果存在),或者添加一个包含declare module 'express';的新声明(.d.ts)文件\
- 尝试使用
-
解决方法\
- 1.declare(新建一个express.d.ts文件,写declare var express: () => any;,然后index.ts就可以直接用express()了)\
- 2.npm i --save-dev @types/express\
-
@types 究竟是干什么的?\
- 是做声明文件的\
-
19.Mixins 混入(合并)\
-
对象混入\
- 合并对象(Object.assign(a, b, c);)是es6新增的\
- let obj = Object.assign(a, b, c);得到(let obj: Name & Age & Sex)交叉类型\
- 类的混入\
-
-
20.修饰器 Decorator\
- 好处:增加代码可读性,使用方便,增加或修改类的功能\
- 配置文件启用:"experimentalDecorators": true,\
- 构造修饰器:const watcher: ClassDecorator = () => {};\
- 使用修饰器:@watcher\
-
21.1.Rollup 构建 TS 项目\
-
为什么选择Rollup?\
- 因为webpack打包出来体积比较大,而Rollup打包体积比较小,适合开发小框架、小控件、小项目\
- 入口文件(input: "./src/index.ts",)\
- 出口文件(output: {file: path.resolve(__dirname, './lib/index.js'),format: 'umd' })\
- 帮我们读tsconfig.json:import ts from 'rollup-plugin-typescript2'\
- 启动网页:import serve from 'rollup-plugin-serve'\
- 热更新:import livereload from 'rollup-plugin-livereload'\
- 代码压缩:import { terser } from 'rollup-plugin-terser'\
- 指定NODE_ENV的值:cross-env NODE_ENV=development\
- 注册到全局都可以使用:import replace from 'rollup-plugin-replace'\
-
-
21.2.webpack 构建 TS 项目\
-
安装(NPM)\
- :webpack-cli\
- 热更新(自带):webpack-dev-server\
- 帮我们解析TS:ts-loader\
- HTML的模板:html-webpack-plugin\
-
配置(webpack.config.js)\
- const path = require('path')\
- const htmpwebpackplug = require('html-webpack-plugin')\
- entry入口、mode开发或生产、output出口、module模块、devServer启动配置、resolve文件后缀、plugins热更新\
-
-
22.TS 编写发布订阅模式\
- 发布订阅模式概述:收集事件做统一处理,例如addEventListener、Vue eventBus\
-
23.TS 进阶 proxy(代理对象) 和 Reflect(操作对象get/set)\
-
proxy(对象形式代理)\
- 手写实现事件监听器\
-
Reflect\
- 概念:有一个对象,帮我们取值,操作对象(查找和设置)\
-
Reflect.get方法(查找值)\
- 设let obj = { name:'张三' },执行Reflect.get( obj, 'name' ),查找输出'张三'\
-
Reflect.set方法(设置值)\
- 设let obj = { name:'张三' },执行Reflect.set( obj, 'name','李四' ),修改设置obj = { name:'李四' }\
-
-
24.TS 进阶用法 Partial(元素改为可选填) 和 Pick(元素摘选出新类型,过滤元素)\
- TS内置该机类型Partial 和 Pick\
- 设type Person = {name: string;age: number;text: string;};\
-
Partial类型\
- 执行type p = Partial;,将Person取值全改为可选(?:)的了\
-
Pick类型\
- 执行type p = Pick<Person, "age">;,将元素age摘选出新类型p,过滤元素\
-
25.TS 进阶用法 Record(约束key和value) 和 Readonly(把每个属性变成只读的)\
-
Record\
- type B = Record<K, Person>;\
- 帮助我们约束key和value\
-
Readonly\
- type man = Readonly;\
- 每个元素面前加个readonly\
-
-
26.TS 进阶用法 infer(充当占位符,实现条件类型推断)\
- infer不是一个类型,一般用于extends后面\
-
拓展知识:\
- const path = require('path')\
- path.resolve() 方法会将路径或路径片段的序列解析为绝对路径。\
- path.join()方法拼接路径\
-