# typescript-basic **Repository Path**: hzy45/typescript-basic ## Basic Information - **Project Name**: typescript-basic - **Description**: coderwhy的ts课程代码 融合,方便学习测试 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-06-22 - **Last Updated**: 2024-07-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 进度:4 下 2:48 //红蜘蛛电子教室 # 运行 ts 代码 ## 方案一 - npm install typescript -g - tsc test.ts //就会将该文件编译成 js 文件 - index.html 里引入该 js 文件 ## 方案二 - webpack 配置本地 ts 编译环境并开启一个本地服,可直接运行在浏览器上(主要靠 ts-loader) ## 方案三 - 通过 ts-node 库,为 ts 的运行提供运行环境(用该方式) - ts-node 需要依赖两个包 tslib @types/node (不装实测不影响 打包压缩代码/node 类型提示) - npm install ts-node -g - npm install tslib @types/node -g - ts-node test.ts # 重要 > ts 是一种可以支持类型编程的类型系统 > > ts 会类型推导,用 let 声明自变量 赋给初始值即可。实在不行再显式声明类型。 > TypeScript 对于类型检测的时候使用的鸭子类型 只关心属性和行为, 不关心你具体是不是对应的类型 ```js let arr = [1, 2, 3]; // arr["1"] 和 arr[1] 结果都是2 ``` ## extends > 把 extedns 理解为,新生成的类型里 一定含有继承的类型里的属性,即该类型变量里一定含有继承的类型里的属性 - 一般来说 interface 里用 extends,是在一个接口基础上增加属性 ```typescript // interface内属性的每一项,后面;可加可不加 interface IPerson { name: string; age: number; } interface IKun extends IPerson { slogan: string; } const ikun: IKun = { name: "why", age: 18, slogan: "你干嘛, 哎呦", }; ``` - 泛型里,可以直接 extends 一个联合类型 ```typescript // 此处 extends一个联合类型,说明**实际传入类型 必在该联合类型内** function getObjectProperty(obj: O, key: K) { return obj[key]; } const info = { name: "why", age: 18, }; const name = getObjectProperty(info, "name"); ``` * 类型extends类型 三元运算 ```typescript // 举个栗子: 函数的重载 // function sum(num1: number, num2: number): number // function sum(num1: string, num2: string): string // 可替代函数重载上面的写法 function sum( num1: T, num2: T ): T extends number ? number : string; // 类型运算 只能用三元运算符,不支持if判断。interface也同样 // A extends B ,只要A里含有B 即为true type returnType = T extends number ? number : string ``` ## any 和 unkown - any 类型,任何操作都合法。unknown 类型,任何操作都不合法[赋值除外](需要类型缩小 或者 断言) ## 元组使用场景 在函数中使用元组类型是最多的(函数的返回值)//返回一个数组,里面含多种类型的返回值 // 其实函数返回一个对象更好,干嘛返回数组,数组位置来决定内容容易出错 ## interface 和 type - type 常用于普通类型,interface 用于对象 - interface 可以重复声明,会合并。也可通过 extends 继承**对象就用 interface** 05_ts 面向对象/13 注意:interface里有属性是函数时//调用签名 ```typescript interface SearchFunc { (source: string, subString: string): boolean; } ``` 有属性名不清楚的,用 索引签名 ```typescript interface StringArray { [index: number]: string; } let myArray: StringArray; myArray = ["Bob", "Fred"]; let myStr: string = myArray[0]; ``` **type extends type** ```typescript type Name = { name: string; } type User = Name & { age: number }; ``` ## keyof const info = { name: "why", age: 18, }; ## 类型缩小 narrowing - typeof - ===/!== - instanceof - in 等等 ## ts 配置 - tsc --init //会生成 tsconfig.json 文件,里面配置 ts 检测规则 ## this - ThisType ```typescript // ThisType: 用于绑定一个上下文的this interface IState { name: string; age: number; } interface IStore { state: IState; eating: () => void; running: () => void; } // 指定this的type是IState,使用this.xx时可以用IState声明的属性。IStore & IState 会导致store上多了name和age属性 const store: IStore & ThisType = { state: { name: "why", age: 18, }, eating: function () { console.log(this.name); }, running: function () { console.log(this.name); }, }; ``` ## class 构造时使用修饰符 - public 虽然是默认,但这种写法里不能忽略,忽略了会认为 name 没声明 ``` class Person { // 语法糖 constructor(public name: string, private _age: number, readonly height: number) { } running() { console.log(this._age, "eating") } } ``` ## 泛型 平时在开发中我们可能会看到一些常用的名称: - T:Type 的缩写,类型 - K、V:key 和 value 的缩写,键值对 - E:Element 的缩写,元素 - O:Object 的缩写,对象 ## 模块与非模块的判定 - JavaScript 规范声明任何没有 export 的 JavaScript 文件都应该被认为是一个脚本,而非一个模块。 - 在一个脚本文件中,变量和类型会被声明在**共享的全局作用域**,将多个输入文件合并成一个输出文件,或者在 HTML 使用多个 ` ``` ## cdn 引入的包 - 例如在 html 里通过``引入 jquery - 不能当模块引入,使用命名空间更合适 ```ts declare namespace $ { export function ajax(settings: any): any; } ``` # tsconfig.json - 让 TypeScript Compiler 在编译的时候,知道如何去编译 TypeScript 代码和进行类型检测 - 指定了编译项目所需的根目录下的文件以及编译选项 - 当目录中出现了 tsconfig.json 文件,则说明该目录是 TypeScript 项目的根目录 - 让编辑器(比如 VSCode)可以按照正确的方式识别 TypeScript 代码 - 对于哪些语法进行提示、类型错误检测等等 - 可以查看文档对于每个选项的解释:https://www.typescriptlang.org/tsconfig - 当我们开发项目的时候,选择 TypeScript 模板时,tsconfig 文件默认都会帮助我们配置好的; compilerOptions 配置 target: 指定编译的版本,"target": "esnext", 指定的是最新版本的 es 标准,只是为了使用时不报错。实际编译是靠 babel 之类的 loader,基于 .browserlist 来决定编译的版本 默认情况下, lib 选项的值继承自 target, "allowSyntheticDefaultImports": true, 当组件导出属性 export {a,b,c},想要一起引入需要 import \* as xx from "xxx.js" 若通过 export default {a,b,c}引入时 import xx from 'xxxjs' ts 里,配置了上面这个属性后,对于第一种情况导入,也可以用 import xx from 'xxxjs' ,认都会帮助我们配置好的; ## compilerOptions 配置 - target: 指定编译的版本,`"target": "esnext"`, - 指定的是最新版本的 es 标准,只是为了使用时不报错。实际编译是靠 babel 之类的 loader,基于 .browserlist 来决定编译的版本 - 默认情况下, lib 选项的值继承自 target, - `"allowSyntheticDefaultImports": true,` 1. 当组件导出属性`export {a,b,c}`,想要一起引入需要 `import * as xx from "xxx.js"` 2. 若通过`export default {a,b,c}`引入时`import xx from 'xxxjs'` 3. ts 里,配置了上面这个属性后,对于第一种情况导入,也可以用`import xx from 'xxxjs'` # axios 拦截配置 ## 配置实例 - axios 可以被多次配置,覆盖原有的配置 下面这两种方式都可以实现 ajax 请求,只要 config 里 url 和 method 配好 就会请求 - axios(config) - const instance = axios.create(config) - instance(config) - instance.request(config) //request 写不写都行 ## 拦截 - 请求拦截,最先添加的 最后执行(全局/局部/个别请求独有的拦截)执行起来 顺序是反的 - 响应拦截,最新添加,最先执行