# base-typescript **Repository Path**: lisa_zhu2012/base-typescript ## Basic Information - **Project Name**: base-typescript - **Description**: 从0开始学习ts基础知识,到ts在vue,react中的应用 - **Primary Language**: TypeScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-03-23 - **Last Updated**: 2022-05-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # TypeScript @ 2022-01-21 更新 ## 基础篇 官网 [handbook](https://www.typescriptlang.org/docs/handbook/intro.html) 部分 > ECMA(European Computer Manufacturers Association 简称,欧洲计算机制造商协会) http://ts.xcatliu.com/ ### typeScript介绍 TypeScript是微软开发的一个开源的编程语言,2012年推出 > 比较适合大中型项目。 > js-动态类型是指运行时才会进行类型检查;ts-静态类型是指编译阶段就能确定每个变量的类型;ts&js是弱类型(类型系统按照是否允许隐式类型转换来分类,可以分为强类型和弱类型);ts是完全兼容js的,它不会修改js运行时的特性; * 以js为基础构建的语言 * 一个js的超集(完全兼容js,ts扩展了js并增加类型系统) * ts扩展了js,并添加了类型; * 可以在任何支持js的平台中执行; * ts不能被js解析器直接执行; 非异常故障:错别字,未调用函数,基本逻辑错误...... ### typeScript入门 #### 安装TypeScript 1. 在全局环境里安装TS ``` npm install typescript -g 或者 yarn global add typescript ``` 2. 用 **tsc** 命令编译 .ts 文件 app.ts 文件: ``` let title: string = '好好学习' ``` 在命令行里输入以下命令都可以将.ts文件编译为.js文件: ``` tsc ./src/app.ts --outFile ./dist/app.js // 进入到dist文件夹,可以运行node app.js tsc ./src/* --outDir ./dist --watch // 我在执行tsc ./src/* --outDir ./dist --watch时报错,只能执行tsc ./src/app.js --outDir ./dist --watch ``` 3. tsconfig.json 配置文件 解决ts和js冲突问题,在命令行里输入 tsc --init 命令,生成一个 tsconfig.json 配置文件,在此配置文件里修改: ``` "outDir": "./dist", "rootDir": "./src" ``` 这样执行,tsc --watch(自动编译) 就可以了 4. 发出错误(有错误编译的时候不生成js文件) tsc -noEmitOnError hello.ts ### 常用类型 ### 类型缩小 ### 函数 ### 对象类型 ### 类型操控 ### 类 ### 模块 ## 高级篇 官网 reference 部分 ### 声明变量 ### **类型推断** ### 枚举 ### 公共类型 ### Symbols ### 类型兼容性 ### 迭代器和生成器 ### 装饰器 ### JSX ### 混入 ### 三斜线指令 ### 模块 ### 模块解析 ### 命名空间 ### 命名空间与模块 ### 声明合并 ### 声明文件 ## 案例篇 ## 项目篇 ### 基础类型 布尔值、数字、字符串、数组、元组、枚举、any 和 void等。 不太常用的原语:bigint 非常大的整数 symbol 全局唯一引用 变量上的类型注释 let myName: string = '' // 冒号+类型 函数 function greet(name: string): void { console.log("hello", + name) } // 参数类型注释 返回值类型注释 对象类型 function printCoord(pt: { x: number; y: number }) { console.log('坐标的x值为:' + pt.x) console.log('坐标的y值为:' + pt.y) } printCood({x: 3, y: 7}) 联合类型 union let id: number | string function printId(id: number | string) { } // 两个或多个其他类型组成的类型 类型别名 type type Point = {x: number;y: number;} type ID = number | string type UserInputSanitizedString = string function printCood(pt: Point) { } 接口 interface null 不存在 undefined 未初始化的值 ### 元组 Tuple 元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 比如,你可以定义一对值分别为 string和number类型的元组。 ``` // 声明一个元组类型 x let x: [string, number] // 初始化 x x = ['hello', 10] // OK // 无效的初始值 x = [10, 'hello'] // Error ``` ### 枚举enum 枚举类型是对JavaScript标准数据类型的一个补充。 使用枚举类型可以为一组数值赋予友好的名字。 ``` enum Color { Red, Green, Blue } let c: Color = Color.Green ``` ### any 有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用any类型来标记这些变量: ``` let notSure: any = 4 notSure = "maybe a string instead" // OK 赋值了一个字符串 notSure = false // OK 赋值了一个布尔值 ``` ### void 某种程度上来说,void类型像是与any类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void: ``` function echo(): void { console.log('做真实的自己,用良心做教育') } ``` ### 类型断言 as const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement // 返回某种类型的HTMLElement const myCanvas2 = document.getElementById("main_canvas") const x = ('hello' as unknown) as number; // ('hello' as any) as number ## 类型缩小 typeof 类型守卫 typeof strs === 'object' // string number bigint boolean symbol undefined function ### 真值缩小 function getUsersOnlineMessage(numUsersOnline: number) { if (numUsersOnline) { return `现在共有${numUsersOnline}人在线!` } return "现在没有人在线. :(" } 0 NaN "" 0n(bigint零的版本) null undefined Boolean("hello") // type: boolean, value: true !!"world" // type: true, value: true ### 等值缩小 === !== == != ### in 操作符缩小 "value" in x ### instanceof 操作符缩小 x instanceof Foo ### 分配缩小 // let x: string | number let x = Math.random() < 0.5 ? 10 : "hello world"; // let x: number x = 1 // let x: string x = 'goodbye' ### 控制流分析 ### 使用类型谓词 function isFish(pet: Fish | Bird): pet is Fish { return (pet as Fish).swim !== undefined } ### 受歧视的unions ### never 类型与穷尽性检查 never 不应该存在的状态 ## 函数 ### 函数类型表达式 fn: (a: string) => void ### 调用签名 ``` type DescribableFunction = { description: string; (someAry: number): boolean; } ``` ### 构造签名 ``` type SomeConstructor = { new (s: string): Ctor } ``` ### 泛型函数-类型推断 ```js function firstElement(arr: any[]) { return arr[0]; } function firstElement(arr: Type[]): Type | undefined { return arr[0] } const s = firstElement(['a', 'b']) const n = firstElement([1, 2]) const u = firstElement([]) ``` ### 泛型函数-限制条件 ```js function longest(a: Type, b: Type) { if (a.length >= b.length) { return a; } else { return b; } } ``` ### 泛型函数-使用受限值 ```js function minimumLength(obj: Type, minimum: number): Type { if (obj.length >= minimum) { return obj } else { return { length: minimum } } } ``` ### 泛型函数-指定类型参数 ``` const arr = combine([1, 2, 3], ["hello"]) ``` ### 编写优秀通用函数的准则 1. 可能的情况下,使用类型参数本身,而不是对其进行约束 2. 总是尽可能少地使用类型参数 3. 如果一个类型的参数只出现在一个地方,请重新考虑你是否真的需要它 ### 函数的可选参数 ``` function fn(n: number) { console.log(n.toFixed()) console.log(n.toFixed(3)) } ``` ### 回调中的可选参数 当为回调写一个函数类型时,永远不要写一个可选参数,除非你打算在不传递该参数的情况下调用函数。 ### 函数重载-基本语法 前两个函数称为:重载签名 第三个函数称为:实现签名 ``` function makeDate(timestamp: number): Date; function makeDate(m: number, d: number, y: number): Date; function makeDate(mOriTimestamp: number, d?: number, y?: number): Date { // ... } ``` ### 函数重载-重载签名和实现签名 参数不正确 参数类型不正确 返回类型不正确 ### 函数重载-编写好的重载 在可能的情况下,总是倾向于使用联合类型的参数而不是重载函数 ### 函数重载-函数内this的声明 ``` const user = { id: 123, admin: false, becomeAdmin: function() { this.admin = true } } interface DB { filterUsers(filter: (this: User) => boolean): User[] } ``` ### void object unknown never Function ### 参数展开运算符-形参展开 ### 参数展开运算符-实参展开 ### 参数解构 ### 返回void类型 ### 认识对象类型 ### 可选属性 ### 只读属性 ### 索引签名 ### 扩展类型 ### 交叉类型 ### 处理冲突 ### 泛型对象类型 打蛋器 曲奇饼干模子 模具 一次性手套 烤箱 夹子 玻璃碗 称 食物:蔓越莓 糖粉 黄油 ## ts+react 1. 框架搭建 2. 入门基础、基本配置 3. 函数式组件中的应用 4. 类组件的应用 5. context 组件间数据共享 6. request 封装 7. 受控组件和非受控组件 > 受控组件:数据渲染完全被属性所控制 ### 安装命令 全局安装react npm install -g create-react-app 搭建ts框架 create-react-app ts-react --typescript 切换到ts-react并运行 yarn start 运行时报了如下错误: 解决办法:将package.json中,"typescript": "~3.7.5"版本,更新ts到"typescript": "^3.8.3" npm install typescript@3.8.3 -S ``` TypeScript error in E:/demo/ts/base-typescript/ts-react-basic/node_modules/@types/testing-library__react/node_modules/pretty-format/build/index.d.ts(7,13): '=' expected. TS1005 5 | * LICENSE file in the root directory of this source tree. 6 | */ > 7 | import type * as PrettyFormat from './types'; | ^ 8 | /** 9 | * Returns a presentation string of your `val` object 10 | * @param val any potential JavaScript object ``` 使用ts应用跟以前的差异 js --> ts jsx --> tsx .d.ts 声明文件 在代码中使用ts的优势在哪里? 团队多人协作,代码提示,组件类型规范,维护性高 #### type和interface可以通用,差别是 type 在一个组件某一个地方要用的时候 interface 多个模块多个组件都要实现对应的数据对象,单独定义一个interface文件 类型别名 type 不能通过同名的方式拓展 ```js // 扩展接口 interface IAnimal { name: string } interface Bear extends IAnimal { honey: boolean } const bear: Bear = { name: 'winnie', honey: true } // type 交叉扩展 type TAnimal = { name: string } type Bear = TAnimal & { honey: Boolean } // 向现有的类型添加字段 interface MyWindow { count: number } interface MyWindow { title: string } const w: MyWindow = { title: '111', count: 100 } // 类型创建后是不能更改的 类型别名 type 不能通过同名的方式拓展的 ``` ### Context ### redux > 在项目中一般Context和redux,二选一 yarn add redux react-redux 在根节点App.tsx引入react-redux 的时候报错,可能需要ts的声明文件 yarn add @types/react-redux ## ts+vue 1. 类组件定义 2. 函数式组件定义 3. 扩展型组件定义 4. 装饰器实现props,watch,ref 5. vuex + ts 6. vue-router + ts 7. axios类型声明文件与封装 ### 安装命令 全局安装 npm i -g @vue/cli vue create 目录 | . (点在当前目录下创建项目) > 安装以上命令提示,安装的版本是vue-cli 3,但是我还不想升级到3,所以copy其它demo代码,npm install来使用了 安装过程中 * 自定义Manually select features:勾选babel,typescript选项 * use class-style component syntax? --> yes * in dedicated config files 通过命令行查询可用的包的版本号 npm view vue-cli versions --json 运行:npm run serve ### 配置文件 tsconfig.json:配置ts编译环境 xx.d.ts 类型声明文档:支持vue,jsx,ts写法 ### 定义组件: src/components 1. 类式 ``` ``` 2. 扩展式 ``` ``` 3. 函数式 ``` ``` ### vue-router npm i vue-router -S ### axios 和 axios的声明文件 npm i axios @types/axios -S ### vuex > 不需要安装声明文件,因为是vue官方所支持的(vue add) npm i vuex -S npm i vuex-class -S