[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"chapter-book:Lb6GZKer":3,"chapter:n26qoyXx":133},{"id":4,"created_at":5,"updated_at":5,"code":6,"author_id":7,"title":8,"slug":9,"cover_theme_key":10,"visibility":11,"status":12,"sort_order":4,"favorite_count":13,"view_count":14,"author":15,"chapter_count":26,"word_count":27,"free_count":13,"is_favorite":24,"book_status":12,"unparted":28},12,"2024-10-03T14:23:57.581+08:00","Lb6GZKer",1,"从零开始学习TypeScript","从零开始学习typescript-12","default","public","published",0,3,{"id":7,"created_at":16,"updated_at":17,"code":18,"username":19,"display_name":20,"role":21,"avatar_url":22,"is_active":23,"is_banned":24,"follower_count":13,"following_count":14,"last_login_at":25},"2023-11-30T23:53:12.952+08:00","2026-10-20T16:16:54.352+08:00","Mg87g8Gk","1701359592888","大苹果","verified_author","\u002Fcuts\u002F17021220625513129.png",true,false,"2026-10-20T16:12:35+08:00",13,52349,[29,37,45,53,61,69,77,85,93,101,109,117,125],{"id":30,"created_at":31,"updated_at":31,"code":32,"author_id":7,"book_id":4,"slug":33,"article_id":34,"title":35,"sort_order":30,"content":36,"status":12},133,"2024-10-03T14:27:10.592+08:00","M9XdeYKJ","typescript学习大纲-133",546,"TypeScript学习大纲","TypeScript 是 JavaScript 的超集，提供了类型系统和现代编程特性，使得开发大型应用更加安全和高效。以下是从入门到精通的学习大纲：\n\n### 入门阶段\n\n1. **TypeScript简介**\n\n   - 什么是TypeScript？\n   - TypeScript与JavaScript的关系\n   - TypeScript的优势\n2. **环境搭建**\n\n   - 安装Node.js\n   - 安装TypeScript编译器（tsc）\n   - 配置IDE（如VS Code）\n3. **基础语法**\n\n   - 变量声明（let, const, var）\n   - 数据类型（基本类型、数组、元组、枚举）\n   - 函数声明与箭头函数\n   - 接口与类型别名\n\n### 中级阶段\n\n4. **面向对象编程**\n\n   - 类与继承\n   - 修饰符（public, private, protected）\n   - 抽象类与接口\n5. **高级类型**\n\n   - 联合类型与交叉类型\n   - 类型保护与类型推断\n   - 映射类型与条件类型\n6. **泛型**\n\n   - 泛型函数\n   - 泛型类\n   - 泛型接口\n\n### 高级阶段\n\n7. **TypeScript工具与配置**\n\n   - tsconfig.json详解\n   - 类型声明文件（@types）\n   - 使用第三方库（如React, Angular等）\n8. **TypeScript与前端框架**\n\n   - TypeScript在React中的应用\n   - TypeScript在Vue中的应用\n9. **测试与调试**\n\n   - 单元测试（Jest, Mocha）\n   - 使用调试工具\n\n### 精通阶段\n\n10. **设计模式**\n\n    - 常用设计模式在TypeScript中的实现\n11. **最佳实践**\n\n    - 代码风格与约定\n    - 性能优化\n    - 代码维护与重构\n12. **项目实践**\n\n    - 完成一个实际项目（如小型应用或工具）\n\n### 进阶阅读\n\n- 深入学习TypeScript的官方文档\n- 相关书籍与在线课程推荐\n\n随着学习的深入，尝试在实际项目中应用TypeScript，以巩固所学知识和技能。\n",{"id":38,"created_at":39,"updated_at":39,"code":40,"author_id":7,"book_id":4,"slug":41,"article_id":42,"title":43,"sort_order":38,"content":44,"status":12},134,"2024-10-03T14:28:04.057+08:00","Qd8ZxbK5","typescript简介-134",547,"TypeScript简介","### TypeScript简介\n\n#### 什么是TypeScript？\n\nTypeScript 是一种由微软开发的开源编程语言，是 JavaScript 的超集。它添加了可选的静态类型和其他现代编程特性，使得开发者能够更安全、高效地构建大型应用程序。TypeScript 的源代码在编译时会转换为标准的 JavaScript，这样就可以在任何支持 JavaScript 的环境中运行。\n\n#### TypeScript与JavaScript的关系\n\n- **超集**：TypeScript 包含了所有 JavaScript 的特性，任何有效的 JavaScript 代码都是有效的 TypeScript 代码。TypeScript 的开发者可以逐步引入类型系统和其他功能，而无需完全重写现有的 JavaScript 代码。\n- **类型系统**：TypeScript 引入了静态类型，允许开发者在编译时捕捉类型错误，而 JavaScript 是动态类型的，类型错误通常在运行时才会暴露。\n- **编译**：TypeScript 需要经过编译成 JavaScript 才能在浏览器或 Node.js 中运行。编译器在此过程中会进行类型检查，帮助识别潜在错误。\n\n#### TypeScript的优势\n\n1. **类型安全**：TypeScript 提供了静态类型检查，能够在编译阶段捕捉类型错误，从而减少运行时错误。\n2. **更好的开发体验**：通过 IDE 支持，TypeScript 提供了更好的自动完成功能、代码重构工具和文档提示，提升开发效率。\n3. **代码可读性**：类型定义使代码更加自解释，增强了团队协作和代码维护的便利性。\n4. **现代特性**：TypeScript 支持许多现代 JavaScript 特性（如 async\u002Fawait、模块化等），同时还提供了一些额外的特性（如接口、泛型等）。\n5. **广泛的社区支持**：TypeScript 的用户基础不断增长，许多流行的框架（如 Angular、React）都原生支持 TypeScript，并有丰富的第三方类型声明库。\n\n通过这些优势，TypeScript 能够帮助开发者构建更加可靠和可维护的应用程序，特别是在大型项目中。\n",{"id":46,"created_at":47,"updated_at":47,"code":48,"author_id":7,"book_id":4,"slug":49,"article_id":50,"title":51,"sort_order":46,"content":52,"status":12},135,"2024-10-03T14:29:43.116+08:00","VzXNPP6g","typescript环境搭建-135",548,"TypeScript环境搭建","### 环境搭建\n\n#### 1. 安装Node.js\n\n- **下载**：访问 [Node.js官网](https:\u002F\u002Fnodejs.org\u002F)，下载适合你操作系统的安装包（LTS版本推荐）。\n- **安装**：按照提示进行安装，确保选择“Add to PATH”选项，以便在命令行中使用 `node` 和 `npm` 命令。\n- **验证**：安装完成后，在终端或命令提示符中输入以下命令，确认安装成功：\n  ```bash\n  node -v\n  npm -v\n  ```\n\n#### 2. 安装TypeScript编译器（tsc）\n\n- **通过npm安装**：在终端中输入以下命令安装 TypeScript：\n  ```bash\n  npm install -g typescript\n  ```\n- **验证安装**：输入以下命令，确认 TypeScript 编译器安装成功：\n  ```bash\n  tsc -v\n  ```\n\n#### 3. 配置IDE（如VS Code）\n\n- **下载VS Code**：访问 [Visual Studio Code官网](https:\u002F\u002Fcode.visualstudio.com\u002F)，下载并安装适合你操作系统的版本。\n- **安装TypeScript插件**：打开 VS Code，前往扩展市场（左侧栏的四个方块图标），搜索并安装“TypeScript Hero”或“TypeScript Extension Pack”等相关插件，以增强TypeScript开发体验。\n- **设置工作区**：创建一个新文件夹作为你的 TypeScript 项目目录，使用 VS Code 打开该文件夹，便于管理文件。\n\n完成这些步骤后，你的 TypeScript 开发环境就搭建好了，可以开始编写 TypeScript 代码了！\n",{"id":54,"created_at":55,"updated_at":55,"code":56,"author_id":7,"book_id":4,"slug":57,"article_id":58,"title":59,"sort_order":54,"content":60,"status":12},136,"2024-10-03T14:31:34.054+08:00","MwKBG767","typescript基础语法-136",549,"TypeScript基础语法","### 基础语法\n\n#### 1. 变量声明（let, const, var）\n\n- **let**：用于声明可变变量，作用域为块级作用域。\n- **const**：用于声明常量，值不可修改，作用域为块级作用域。\n- **var**：用于声明变量，作用域为函数作用域或全局作用域，已不推荐使用。\n\n**示例：**\n\n```typescript\nlet count: number = 10; \u002F\u002F 可变变量\nconst maxCount: number = 100; \u002F\u002F 常量\nvar total: number = 0; \u002F\u002F 传统声明方式，使用较少\n\nif (true) {\n    let innerCount = 5; \u002F\u002F innerCount 在此块内有效\n    console.log(innerCount); \u002F\u002F 输出：5\n}\n\u002F\u002F console.log(innerCount); \u002F\u002F 报错：innerCount 在此块外无效\n```\n\n#### 2. 数据类型\n\n- **基本类型**：\n\n  - `number`: 数字类型\n  - `string`: 字符串类型\n  - `boolean`: 布尔类型\n  - `null` 和 `undefined`: 分别表示无值和未定义\n- **数组**：用 `number[]` 或 `Array\u003Cnumber>` 表示数字数组。\n- **元组**：用来表示固定数量和类型的数组。\n- **枚举**：定义命名常量的集合，便于可读性。\n\n**示例：**\n\n```typescript\nlet age: number = 30; \u002F\u002F 基本类型\nlet name: string = \"Alice\"; \u002F\u002F 基本类型\nlet isActive: boolean = true; \u002F\u002F 基本类型\n\nlet scores: number[] = [85, 90, 78]; \u002F\u002F 数组\nlet person: [string, number] = [\"Bob\", 25]; \u002F\u002F 元组\n\nenum Color {\n    Red,\n    Green,\n    Blue\n}\nlet favoriteColor: Color = Color.Green; \u002F\u002F 枚举\n```\n\n#### 3. 函数声明与箭头函数\n\n- **函数声明**：使用 `function` 关键字定义的函数。\n- **箭头函数**：使用箭头语法（`=>`）定义的函数，通常用于简化函数书写。\n\n**示例：**\n\n```typescript\n\u002F\u002F 普通函数\nfunction add(a: number, b: number): number {\n    return a + b;\n}\n\n\u002F\u002F 箭头函数\nconst multiply = (x: number, y: number): number => {\n    return x * y;\n};\n\n\u002F\u002F 单行箭头函数\nconst square = (n: number): number => n * n;\n\nconsole.log(add(5, 10)); \u002F\u002F 输出：15\nconsole.log(multiply(4, 5)); \u002F\u002F 输出：20\nconsole.log(square(6)); \u002F\u002F 输出：36\n```\n\n#### 4. 接口与类型别名\n\n- **接口**：定义对象的结构，可以包含属性和方法，支持继承。\n- **类型别名**：用于给任何类型（包括基础类型、对象、联合类型等）一个名称。\n\n**示例：**\n\n```typescript\n\u002F\u002F 接口\ninterface Person {\n    name: string;\n    age: number;\n    greet(): void;\n}\n\nconst user: Person = {\n    name: \"Alice\",\n    age: 30,\n    greet() {\n        console.log(`Hello, my name is ${this.name}`);\n    }\n};\n\nuser.greet(); \u002F\u002F 输出：Hello, my name is Alice\n\n\u002F\u002F 类型别名\ntype Point = {\n    x: number;\n    y: number;\n};\n\nconst p: Point = { x: 10, y: 20 }; \u002F\u002F 使用类型别名\n```\n\n以上是 TypeScript 基础语法的详细说明和示例，通过这些基础知识，你可以开始编写更复杂的 TypeScript 程序。\n",{"id":62,"created_at":63,"updated_at":63,"code":64,"author_id":7,"book_id":4,"slug":65,"article_id":66,"title":67,"sort_order":62,"content":68,"status":12},137,"2024-10-03T14:32:35.264+08:00","q28kdEXl","typescript面向对象编程-137",550,"TypeScript面向对象编程","### 面向对象编程\n\n#### 1. 类与继承\n\n在 TypeScript 中，类是创建对象的蓝图。可以通过继承来创建一个新类，使其具有父类的特性和功能。\n\n**示例：**\n\n```typescript\nclass Animal {\n    protected name: string; \u002F\u002F 保护属性，子类可以访问\n\n    constructor(name: string) {\n        this.name = name;\n    }\n\n    speak(): void {\n        console.log(`${this.name} makes a noise.`);\n    }\n}\n\nclass Dog extends Animal { \u002F\u002F 继承\n    speak(): void {\n        console.log(`${this.name} barks.`);\n    }\n}\n\nconst dog = new Dog(\"Buddy\");\ndog.speak(); \u002F\u002F 输出：Buddy barks.\n```\n\n#### 2. 修饰符\n\nTypeScript 支持三种访问修饰符：\n\n- **public**：公共的，任何地方都可以访问（默认修饰符）。\n- **private**：私有的，仅在类内部可访问。\n- **protected**：受保护的，可以在类及其子类中访问。\n\n**示例：**\n\n```typescript\nclass Person {\n    public name: string; \u002F\u002F 公开属性\n    private age: number; \u002F\u002F 私有属性\n    protected job: string; \u002F\u002F 受保护属性\n\n    constructor(name: string, age: number, job: string) {\n        this.name = name;\n        this.age = age;\n        this.job = job;\n    }\n\n    public introduce(): void {\n        console.log(`Hello, I am ${this.name}, and I work as a ${this.job}.`);\n    }\n\n    private getAge(): number {\n        return this.age;\n    }\n}\n\nconst person = new Person(\"Alice\", 30, \"Engineer\");\nperson.introduce(); \u002F\u002F 输出：Hello, I am Alice, and I work as a Engineer.\n\u002F\u002F console.log(person.age); \u002F\u002F 报错：属性 'age' 是私有的\n```\n\n#### 3. 抽象类与接口\n\n- **抽象类**：不能被实例化的类，通常用于定义基类。抽象类可以包含抽象方法（没有实现的方法）和具体方法。\n- **接口**：用于定义对象的结构，可以被类实现。接口只定义属性和方法，没有实现。\n\n**示例：**\n\n```typescript\n\u002F\u002F 抽象类\nabstract class Shape {\n    abstract area(): number; \u002F\u002F 抽象方法\n\n    printArea(): void {\n        console.log(`Area: ${this.area()}`);\n    }\n}\n\nclass Circle extends Shape {\n    constructor(private radius: number) {\n        super();\n    }\n\n    area(): number {\n        return Math.PI * this.radius ** 2; \u002F\u002F 实现抽象方法\n    }\n}\n\nconst circle = new Circle(5);\ncircle.printArea(); \u002F\u002F 输出：Area: 78.53981633974483\n\n\u002F\u002F 接口\ninterface Vehicle {\n    speed: number; \u002F\u002F 属性\n    drive(): void; \u002F\u002F 方法\n}\n\nclass Car implements Vehicle { \u002F\u002F 实现接口\n    constructor(public speed: number) {}\n\n    drive(): void {\n        console.log(`Driving at ${this.speed} km\u002Fh`);\n    }\n}\n\nconst car = new Car(120);\ncar.drive(); \u002F\u002F 输出：Driving at 120 km\u002Fh\n```\n\n### 总结\n\n通过类与继承、访问修饰符、抽象类和接口，TypeScript 提供了强大的面向对象编程特性，可以帮助开发者创建结构良好、可维护性高的代码。\n",{"id":70,"created_at":71,"updated_at":71,"code":72,"author_id":7,"book_id":4,"slug":73,"article_id":74,"title":75,"sort_order":70,"content":76,"status":12},138,"2024-10-03T14:33:55.63+08:00","n26qoyXx","typescript高级类型-138",551,"TypeScript高级类型","### 高级类型\n\n#### 1. 联合类型与交叉类型\n\n- **联合类型**：表示变量可以是多种类型中的一种，使用 `|` 符号。\n- **交叉类型**：将多个类型合并为一个类型，使用 `&` 符号。\n\n**示例：**\n\n```typescript\n\u002F\u002F 联合类型\nfunction printId(id: number | string): void {\n    console.log(`Your ID is: ${id}`);\n}\n\nprintId(101); \u002F\u002F 输出：Your ID is: 101\nprintId(\"202\"); \u002F\u002F 输出：Your ID is: 202\n\n\u002F\u002F 交叉类型\ninterface Person {\n    name: string;\n    age: number;\n}\n\ninterface Contact {\n    email: string;\n}\n\ntype Employee = Person & Contact; \u002F\u002F 合并类型\n\nconst employee: Employee = {\n    name: \"Alice\",\n    age: 30,\n    email: \"alice@example.com\"\n};\n\nconsole.log(employee); \u002F\u002F 输出：{ name: 'Alice', age: 30, email: 'alice@example.com' }\n```\n\n#### 2. 类型保护与类型推断\n\n- **类型保护**：通过条件语句检查变量类型，确保在访问特定属性时类型安全。\n- **类型推断**：TypeScript 自动推断变量的类型。\n\n**示例：**\n\n```typescript\nfunction getLength(value: string | string[]): number {\n    if (typeof value === \"string\") {\n        return value.length; \u002F\u002F 类型保护\n    } else {\n        return value.length; \u002F\u002F 依然有效，因为 value 是 string[]\n    }\n}\n\nconsole.log(getLength(\"Hello\")); \u002F\u002F 输出：5\nconsole.log(getLength([\"Hello\", \"World\"])); \u002F\u002F 输出：2\n\n\u002F\u002F 类型推断\nlet inferredType = [1, 2, 3]; \u002F\u002F TypeScript 推断为 number[]\ninferredType.push(4);\nconsole.log(inferredType); \u002F\u002F 输出：[1, 2, 3, 4]\n```\n\n#### 3. 映射类型与条件类型\n\n- **映射类型**：创建基于现有类型的新类型，可以对属性进行修改。\n- **条件类型**：根据条件表达式的结果选择类型。\n\n**示例：**\n\n```typescript\n\u002F\u002F 映射类型\ntype Person = {\n    name: string;\n    age: number;\n};\n\n\u002F\u002F 将所有属性变为只读\ntype Readonly\u003CT> = {\n    readonly [K in keyof T]: T[K];\n};\n\ntype ReadonlyPerson = Readonly\u003CPerson>;\n\nconst readonlyPerson: ReadonlyPerson = {\n    name: \"Bob\",\n    age: 25\n};\n\u002F\u002F readonlyPerson.age = 30; \u002F\u002F 报错：无法分配到 \"age\"，因为它是只读属性\n\n\u002F\u002F 条件类型\ntype IsString\u003CT> = T extends string ? \"Yes\" : \"No\";\n\ntype Test1 = IsString\u003Cstring>; \u002F\u002F \"Yes\"\ntype Test2 = IsString\u003Cnumber>; \u002F\u002F \"No\"\n\nconst test1: Test1 = \"Yes\"; \u002F\u002F 合法\nconst test2: Test2 = \"No\"; \u002F\u002F 合法\n```\n\n### 总结\n\n通过联合类型与交叉类型、类型保护与类型推断，以及映射类型与条件类型，TypeScript 提供了强大的类型系统，使得开发者能够更灵活、安全地处理数据，提升代码的可维护性和可读性。\n",{"id":78,"created_at":79,"updated_at":79,"code":80,"author_id":7,"book_id":4,"slug":81,"article_id":82,"title":83,"sort_order":78,"content":84,"status":12},139,"2024-10-03T14:34:57.415+08:00","Wk8YA58G","typescript泛型-139",552,"TypeScript泛型","### 泛型\n\n泛型是一种强大的特性，它允许开发者定义可以接收不同类型参数的函数、类和接口，从而提高代码的复用性和灵活性。\n\n#### 1. 泛型函数\n\n泛型函数允许在函数声明时定义一个或多个类型参数，从而可以在函数体内使用这些参数作为类型。\n\n**示例：**\n\n```typescript\nfunction identity\u003CT>(arg: T): T {\n    return arg;\n}\n\nconst str = identity\u003Cstring>(\"Hello\"); \u002F\u002F 指定类型为 string\nconst num = identity\u003Cnumber>(123); \u002F\u002F 指定类型为 number\n\nconsole.log(str); \u002F\u002F 输出：Hello\nconsole.log(num); \u002F\u002F 输出：123\n```\n\n#### 2. 泛型类\n\n泛型类允许类在声明时使用类型参数，从而可以为类的属性和方法定义灵活的类型。\n\n**示例：**\n\n```typescript\nclass GenericBox\u003CT> {\n    private value: T;\n\n    constructor(value: T) {\n        this.value = value;\n    }\n\n    getValue(): T {\n        return this.value;\n    }\n}\n\nconst stringBox = new GenericBox\u003Cstring>(\"Hello\");\nconst numberBox = new GenericBox\u003Cnumber>(42);\n\nconsole.log(stringBox.getValue()); \u002F\u002F 输出：Hello\nconsole.log(numberBox.getValue()); \u002F\u002F 输出：42\n```\n\n#### 3. 泛型接口\n\n泛型接口允许定义带有类型参数的接口，可以用于描述具有特定属性和方法的对象。\n\n**示例：**\n\n```typescript\ninterface Pair\u003CK, V> {\n    key: K;\n    value: V;\n}\n\nconst pair1: Pair\u003Cnumber, string> = { key: 1, value: \"One\" };\nconst pair2: Pair\u003Cstring, boolean> = { key: \"isActive\", value: true };\n\nconsole.log(pair1); \u002F\u002F 输出：{ key: 1, value: 'One' }\nconsole.log(pair2); \u002F\u002F 输出：{ key: 'isActive', value: true }\n```\n\n### 总结\n\n通过泛型函数、泛型类和泛型接口，TypeScript 允许开发者编写更加灵活和可复用的代码。泛型的使用能够显著提高类型安全性和代码的可读性，使得函数和类能够处理不同类型的数据而不丧失类型信息。\n",{"id":86,"created_at":87,"updated_at":87,"code":88,"author_id":7,"book_id":4,"slug":89,"article_id":90,"title":91,"sort_order":86,"content":92,"status":12},140,"2024-10-06T07:48:20.495+08:00","1RKzRvKz","typescript工具与配置-140",553,"TypeScript工具与配置","### tsconfig.json 完整配置说明\n\n`tsconfig.json` 文件是 TypeScript 项目的配置中心，以下是详细的配置选项及其说明，涵盖了多种使用场景，适用于前端和后端开发。\n\n#### 1. `compilerOptions`\n\n- **target**: 指定编译后的 JavaScript 版本（如 `\"ES5\"`、`\"ES6\"`、`\"ESNext\"`）。\n- **module**: 指定使用的模块系统（如 `\"commonjs\"`、`\"esnext\"`、`\"amd\"`、`\"umd\"`）。\n- **lib**: 指定要包含的库文件（如 `[\"ES6\", \"DOM\"]`），用于支持特定的语言特性。\n- **outDir**: 输出目录，编译后的文件存放位置。\n- **rootDir**: 输入文件的根目录。\n- **sourceMap**: 生成源映射文件，方便调试。\n- **declaration**: 生成对应的 `.d.ts` 声明文件。\n- **strict**: 启用所有严格类型检查选项。\n- **noImplicitAny**: 不允许隐式 `any` 类型。\n- **esModuleInterop**: 允许使用默认导入以兼容 CommonJS 模块。\n- **skipLibCheck**: 跳过库文件的类型检查，提高编译速度。\n- **forceConsistentCasingInFileNames**: 强制文件名一致性（在 Windows 上有效）。\n- **baseUrl**: 设置基础 URL，用于模块解析。\n- **paths**: 自定义模块路径映射。\n- **allowSyntheticDefaultImports**: 允许从没有默认导出的模块中默认导入。\n- **moduleResolution**: 指定模块解析策略（如 `\"node\"`）。\n\n**示例 tsconfig.json:**\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES6\",\n    \"module\": \"commonjs\",\n    \"lib\": [\"ES6\", \"DOM\"],\n    \"outDir\": \".\u002Fdist\",\n    \"rootDir\": \".\u002Fsrc\",\n    \"sourceMap\": true,\n    \"declaration\": true,\n    \"strict\": true,\n    \"noImplicitAny\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"baseUrl\": \".\u002Fsrc\",\n    \"paths\": {\n      \"@\u002F*\": [\"*\"]\n    },\n    \"allowSyntheticDefaultImports\": true,\n    \"moduleResolution\": \"node\"\n  },\n  \"include\": [\"src\u002F**\u002F*\"],\n  \"exclude\": [\"node_modules\", \"**\u002F*.spec.ts\"]\n}\n```\n\n#### 2. TypeScript 在前端开发中的使用\n\nTypeScript 可以与多种前端框架结合使用，以下是一些常见框架的集成方式。\n\n- **React**:\n\n  - 安装相关库及类型：\n\n    ```bash\n    npm install react react-dom\n    npm install --save-dev @types\u002Freact @types\u002Freact-dom\n    ```\n  - 示例组件：\n\n    ```tsx\n    import React from 'react';\n\n    interface GreetingProps {\n        name: string;\n    }\n\n    const Greeting: React.FC\u003CGreetingProps> = ({ name }) => {\n        return \u003Ch1>Hello, {name}!\u003C\u002Fh1>;\n    };\n\n    export default Greeting;\n    ```\n- **Angular**:\n\n  - 安装 Angular：\n\n    ```bash\n    npm install @angular\u002Fcore @angular\u002Fcommon\n    npm install --save-dev @types\u002Fnode\n    ```\n  - 示例组件：\n\n    ```typescript\n    import { Component } from '@angular\u002Fcore';\n\n    @Component({\n        selector: 'app-hello',\n        template: `\u003Ch1>Hello, {{ name }}!\u003C\u002Fh1>`,\n    })\n    export class HelloComponent {\n        name: string = 'Angular';\n    }\n    ```\n- **Vue**:\n\n  - 安装 Vue 和类型：\n\n    ```bash\n    npm install vue\n    npm install --save-dev @types\u002Fvue\n    ```\n  - 示例组件：\n\n    ```vue\n    \u003Ctemplate>\n      \u003Ch1>Hello, {{ name }}!\u003C\u002Fh1>\n    \u003C\u002Ftemplate>\n\n    \u003Cscript lang=\"ts\">\n    import { defineComponent } from 'vue';\n\n    export default defineComponent({\n        data() {\n            return {\n                name: 'Vue'\n            };\n        }\n    });\n    \u003C\u002Fscript>\n    ```\n\n#### 3. TypeScript 在后端开发中的使用\n\nTypeScript 也可以用于后端开发，特别是在 Node.js 环境中。\n\n- **设置 Node.js 项目**:\n\n  1. **初始化项目**：\n\n     ```bash\n     mkdir my-backend\n     cd my-backend\n     npm init -y\n     ```\n  2. **安装 TypeScript 和类型定义**：\n\n     ```bash\n     npm install typescript --save-dev\n     npm install @types\u002Fnode --save-dev\n     ```\n  3. **创建 tsconfig.json**：\n\n     ```bash\n     npx tsc --init\n     ```\n- **编写后端代码**：\n  创建一个 `src\u002Findex.ts` 文件，编写 HTTP 服务器示例：\n\n  ```typescript\n  import http from 'http';\n\n  const hostname = '127.0.0.1';\n  const port = 3000;\n\n  const server = http.createServer((req, res) => {\n      res.statusCode = 200;\n      res.setHeader('Content-Type', 'text\u002Fplain');\n      res.end('Hello World\\n');\n  });\n\n  server.listen(port, hostname, () => {\n      console.log(`Server running at http:\u002F\u002F${hostname}:${port}\u002F`);\n  });\n  ```\n- **编译并运行**：\n\n  1. **编译 TypeScript**：\n\n     ```bash\n     npx tsc\n     ```\n  2. **运行生成的 JavaScript**：\n\n     ```bash\n     node dist\u002Findex.js\n     ```\n\n### 4. 使用第三方库\n\n在 TypeScript 中使用第三方库时，确保安装相应的类型定义。例如，使用 `axios`：\n\n```bash\nnpm install axios\nnpm install --save-dev @types\u002Faxios\n```\n\n**示例代码**：\n\n```typescript\nimport axios from 'axios';\n\nasync function fetchData(url: string) {\n    const response = await axios.get(url);\n    return response.data;\n}\n\nfetchData('https:\u002F\u002Fapi.example.com\u002Fdata')\n    .then(data => console.log(data))\n    .catch(err => console.error(err));\n```\n\n### 总结\n\n通过全面的 `tsconfig.json` 配置、在前端和后端开发中的使用，TypeScript 为开发者提供了强大的工具，提升代码的可维护性和类型安全性。无论是在构建大型前端应用还是开发后端服务，TypeScript 都能够显著改善开发体验。\n",{"id":94,"created_at":95,"updated_at":95,"code":96,"author_id":7,"book_id":4,"slug":97,"article_id":98,"title":99,"sort_order":94,"content":100,"status":12},141,"2024-10-06T07:51:46.229+08:00","baXDl7XJ","typescript与前端框架-141",554,"TypeScript与前端框架","### TypeScript 与前端框架\n\nTypeScript 提供了静态类型检查和强大的类型系统，这使得它在多个前端框架中得到了广泛应用。以下是 TypeScript 在 React 和 Vue 中的详细应用说明。\n\n#### 1. TypeScript 在 React 中的应用\n\nReact 是一个用于构建用户界面的库，TypeScript 的引入可以提高组件的可读性和可维护性。以下是一些常见应用场景：\n\n**基本组件的使用**\n\n```tsx\nimport React from 'react';\n\n\u002F\u002F 定义 props 类型\ninterface GreetingProps {\n    name: string;\n}\n\n\u002F\u002F 使用 FC 泛型\nconst Greeting: React.FC\u003CGreetingProps> = ({ name }) => {\n    return \u003Ch1>Hello, {name}!\u003C\u002Fh1>;\n};\n\nexport default Greeting;\n```\n\n**使用状态和副作用**\n\n```tsx\nimport React, { useState, useEffect } from 'react';\n\n\u002F\u002F 定义状态类型\ninterface User {\n    id: number;\n    name: string;\n}\n\nconst UserList: React.FC = () => {\n    const [users, setUsers] = useState\u003CUser[]>([]);\n\n    useEffect(() => {\n        const fetchUsers = async () => {\n            const response = await fetch('\u002Fapi\u002Fusers');\n            const data: User[] = await response.json();\n            setUsers(data);\n        };\n        fetchUsers();\n    }, []);\n\n    return (\n        \u003Cul>\n            {users.map(user => (\n                \u003Cli key={user.id}>{user.name}\u003C\u002Fli>\n            ))}\n        \u003C\u002Ful>\n    );\n};\n\nexport default UserList;\n```\n\n**使用上下文和自定义钩子**\n\n```tsx\nimport React, { createContext, useContext, useState } from 'react';\n\n\u002F\u002F 定义上下文类型\ninterface AuthContextType {\n    isAuthenticated: boolean;\n    login: () => void;\n}\n\n\u002F\u002F 创建上下文\nconst AuthContext = createContext\u003CAuthContextType | undefined>(undefined);\n\n\u002F\u002F 提供者组件\nconst AuthProvider: React.FC = ({ children }) => {\n    const [isAuthenticated, setIsAuthenticated] = useState(false);\n\n    const login = () => setIsAuthenticated(true);\n\n    return (\n        \u003CAuthContext.Provider value={{ isAuthenticated, login }}>\n            {children}\n        \u003C\u002FAuthContext.Provider>\n    );\n};\n\n\u002F\u002F 使用上下文\nconst AuthConsumer: React.FC = () => {\n    const context = useContext(AuthContext);\n    if (!context) throw new Error('AuthConsumer must be used within an AuthProvider');\n\n    return (\n        \u003Cdiv>\n            {context.isAuthenticated ? 'Logged in' : 'Logged out'}\n            \u003Cbutton onClick={context.login}>Login\u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n    );\n};\n\nexport { AuthProvider, AuthConsumer };\n```\n\n#### 2. TypeScript 在 Vue 中的应用\n\nVue 是一个用于构建用户界面的渐进式框架。TypeScript 的使用使得 Vue 组件更加可维护和可扩展。以下是 TypeScript 在 Vue 中的应用示例：\n\n**基本组件的使用**\n\n```vue\n\u003Ctemplate>\n  \u003Ch1>Hello, {{ name }}!\u003C\u002Fh1>\n\u003C\u002Ftemplate>\n\n\u003Cscript lang=\"ts\">\nimport { defineComponent } from 'vue';\n\n\u002F\u002F 定义 props 类型\ninterface Props {\n    name: string;\n}\n\nexport default defineComponent({\n    props: {\n        name: {\n            type: String,\n            required: true\n        }\n    } as const,\n});\n\u003C\u002Fscript>\n```\n\n**使用状态和计算属性**\n\n```vue\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cp>Count: {{ count }}\u003C\u002Fp>\n    \u003Cbutton @click=\"increment\">Increment\u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript lang=\"ts\">\nimport { defineComponent, ref } from 'vue';\n\nexport default defineComponent({\n    setup() {\n        const count = ref(0);\n\n        const increment = () => {\n            count.value++;\n        };\n\n        return { count, increment };\n    }\n});\n\u003C\u002Fscript>\n```\n\n**使用 Vue Router 和 Vuex**\n\n- **Vue Router**:\n\n```typescript\nimport { createRouter, createWebHistory } from 'vue-router';\nimport Home from '.\u002Fviews\u002FHome.vue';\nimport About from '.\u002Fviews\u002FAbout.vue';\n\nconst routes = [\n    { path: '\u002F', component: Home },\n    { path: '\u002Fabout', component: About },\n];\n\nconst router = createRouter({\n    history: createWebHistory(),\n    routes,\n});\n\nexport default router;\n```\n\n- **Vuex**:\n\n```typescript\nimport { createStore } from 'vuex';\n\ninterface State {\n    count: number;\n}\n\nconst store = createStore\u003CState>({\n    state: {\n        count: 0,\n    },\n    mutations: {\n        increment(state) {\n            state.count++;\n        }\n    }\n});\n\nexport default store;\n```\n\n**使用自定义组合函数**\n\n```typescript\nimport { ref } from 'vue';\n\nexport function useCounter() {\n    const count = ref(0);\n    const increment = () => count.value++;\n    const decrement = () => count.value--;\n\n    return { count, increment, decrement };\n}\n```\n\n#### 3. 综合应用场景\n\n- **异步数据获取**: 在组件中使用 Axios 等库进行数据请求时，TypeScript 可以帮助定义返回数据的类型，提高代码的可维护性。\n- **表单处理**: 对于复杂的表单，可以定义表单数据的类型，并使用类型检查确保输入数据的正确性。\n- **组件库**: 使用 TypeScript 开发组件库时，可以通过类型声明文件（.d.ts）提供类型信息给使用者。\n- **错误处理**: 使用 TypeScript 提高错误处理的类型安全性，确保在处理异常时代码的健壮性。\n\n### 总结\n\nTypeScript 的引入使得 React 和 Vue 的开发过程更加清晰和可靠，提供了强大的类型系统以提高代码的可读性和可维护性。通过以上示例，可以看到 TypeScript 在组件定义、状态管理、路由配置及自定义钩子中的广泛应用，极大地提升了开发体验和代码质量。\n",{"id":102,"created_at":103,"updated_at":103,"code":104,"author_id":7,"book_id":4,"slug":105,"article_id":106,"title":107,"sort_order":102,"content":108,"status":12},142,"2024-10-06T07:52:19.814+08:00","jBXgmj6R","测试与调试-142",555,"测试与调试","### 测试与调试 TypeScript 应用\n\n在 TypeScript 项目中，测试与调试是保证代码质量和稳定性的重要步骤。以下是关于单元测试和调试工具的详细说明，涵盖常见场景和使用方法。\n\n#### 1. 单元测试\n\n##### 1.1 使用 Jest 进行单元测试\n\nJest 是一个功能强大的测试框架，广泛用于 JavaScript 和 TypeScript 项目。\n\n**安装 Jest 和 TypeScript 支持**：\n\n```bash\nnpm install --save-dev jest ts-jest @types\u002Fjest\n```\n\n**配置 Jest**：\n在项目根目录下创建 `jest.config.js`：\n\n```javascript\nmodule.exports = {\n  preset: 'ts-jest',\n  testEnvironment: 'node',\n};\n```\n\n**编写测试用例**：\n创建 `src\u002Fsum.ts` 文件：\n\n```typescript\nexport const sum = (a: number, b: number): number => {\n    return a + b;\n};\n```\n\n创建 `src\u002Fsum.test.ts` 文件：\n\n```typescript\nimport { sum } from '.\u002Fsum';\n\ntest('adds 1 + 2 to equal 3', () => {\n    expect(sum(1, 2)).toBe(3);\n});\n```\n\n**运行测试**：\n\n```bash\nnpx jest\n```\n\n##### 1.2 使用 Mocha 进行单元测试\n\nMocha 是另一种流行的测试框架，通常与 Chai 等断言库结合使用。\n\n**安装 Mocha、Chai 和 TypeScript 支持**：\n\n```bash\nnpm install --save-dev mocha chai ts-node @types\u002Fmocha @types\u002Fchai\n```\n\n**编写测试用例**：\n创建 `src\u002Fmultiply.ts` 文件：\n\n```typescript\nexport const multiply = (a: number, b: number): number => {\n    return a * b;\n};\n```\n\n创建 `src\u002Fmultiply.test.ts` 文件：\n\n```typescript\nimport { expect } from 'chai';\nimport { multiply } from '.\u002Fmultiply';\n\ndescribe('multiply', () => {\n    it('should multiply 2 and 3 to equal 6', () => {\n        expect(multiply(2, 3)).to.equal(6);\n    });\n});\n```\n\n**运行测试**：\n\n```bash\nnpx mocha -r ts-node\u002Fregister 'src\u002F**\u002F*.test.ts'\n```\n\n#### 2. 使用调试工具\n\n调试工具帮助开发者发现和修复代码中的错误。以下是常见的调试工具和方法。\n\n##### 2.1 使用 VS Code 调试 TypeScript\n\n1. **设置调试配置**：\n   在 VS Code 中，点击左侧的调试图标，然后点击“创建一个 launch.json 文件”。\n\n   示例 `launch.json` 配置：\n\n   ```json\n   {\n       \"version\": \"0.2.0\",\n       \"configurations\": [\n           {\n               \"type\": \"node\",\n               \"request\": \"launch\",\n               \"name\": \"Launch Program\",\n               \"program\": \"${workspaceFolder}\u002Fdist\u002Findex.js\", \u002F\u002F 入口文件\n               \"preLaunchTask\": \"tsc: build - tsconfig.json\",\n               \"outFiles\": [\"${workspaceFolder}\u002Fdist\u002F**\u002F*.js\"]\n           }\n       ]\n   }\n   ```\n2. **在代码中添加断点**：\n   在 TypeScript 源代码中，点击行号旁边添加断点。\n3. **启动调试**：\n   选择调试配置并点击“开始调试”。调试器将会在断点处暂停，允许你检查变量、调用堆栈等信息。\n\n##### 2.2 使用 Chrome 开发者工具调试前端 TypeScript 应用\n\n1. **生成 Source Maps**：\n   在 `tsconfig.json` 中启用 `sourceMap` 选项：\n\n   ```json\n   {\n       \"compilerOptions\": {\n           \"sourceMap\": true\n       }\n   }\n   ```\n2. **在 Chrome 中打开开发者工具**：\n   按 `F12` 或右键点击页面，选择“检查”。\n3. **使用源面板调试**：\n   在“源”面板中找到你的 TypeScript 文件，你可以设置断点、检查变量值等。\n\n#### 3. 覆盖所有场景的测试与调试\n\n- **集成测试**：除了单元测试，还可以编写集成测试，确保不同模块间的交互正常。使用 Jest 或 Mocha，可以创建类似于上面的测试文件，但涵盖多个模块的协作。\n- **异步测试**：测试异步函数时，可以使用 `async\u002Fawait` 语法。\n\n  ```typescript\n  test('fetches data', async () => {\n      const data = await fetchData('https:\u002F\u002Fapi.example.com\u002Fdata');\n      expect(data).toBeDefined();\n  });\n  ```\n- **UI 组件测试**：在 React 和 Vue 中，使用 React Testing Library 或 Vue Test Utils 进行组件测试。\n- **错误处理测试**：测试在异常情况下的代码行为，例如：\n\n  ```typescript\n  test('throws error when input is invalid', () => {\n      expect(() => { throwErrorFunction(); }).toThrow(Error);\n  });\n  ```\n\n### 总结\n\n通过单元测试和调试工具的结合使用，TypeScript 项目的开发过程变得更加高效和可靠。Jest 和 Mocha 提供了强大的测试能力，而 VS Code 和 Chrome 开发者工具则为调试提供了便利。掌握这些工具和方法，可以有效提升代码质量和开发效率。\n",{"id":110,"created_at":111,"updated_at":111,"code":112,"author_id":7,"book_id":4,"slug":113,"article_id":114,"title":115,"sort_order":110,"content":116,"status":12},143,"2024-10-06T07:55:52.249+08:00","AkKWVaX2","设计模式-143",556,"设计模式","### 设计模式在 TypeScript 中的实现\n\n设计模式是解决软件设计中常见问题的典型方案。以下是常用和不常用的设计模式在 TypeScript 中的实现，包括它们的说明和示例代码。\n\n#### 1. 创建型模式\n\n##### 1.1 单例模式 (Singleton)\n\n确保一个类只有一个实例，并提供全局访问点。\n\n```typescript\nclass Singleton {\n    private static instance: Singleton;\n\n    private constructor() {}\n\n    public static getInstance(): Singleton {\n        if (!Singleton.instance) {\n            Singleton.instance = new Singleton();\n        }\n        return Singleton.instance;\n    }\n}\n\n\u002F\u002F 使用示例\nconst singleton1 = Singleton.getInstance();\nconst singleton2 = Singleton.getInstance();\nconsole.log(singleton1 === singleton2); \u002F\u002F true\n```\n\n##### 1.2 工厂模式 (Factory Method)\n\n定义一个创建对象的接口，但由子类决定实例化哪个类。\n\n```typescript\ninterface Product {\n    operation(): string;\n}\n\nclass ConcreteProductA implements Product {\n    public operation(): string {\n        return 'Result of ConcreteProductA';\n    }\n}\n\nclass ConcreteProductB implements Product {\n    public operation(): string {\n        return 'Result of ConcreteProductB';\n    }\n}\n\nabstract class Creator {\n    public abstract factoryMethod(): Product;\n\n    public someOperation(): string {\n        const product = this.factoryMethod();\n        return `Creator: The same creator's code has just worked with ${product.operation()}`;\n    }\n}\n\nclass ConcreteCreatorA extends Creator {\n    public factoryMethod(): Product {\n        return new ConcreteProductA();\n    }\n}\n\nclass ConcreteCreatorB extends Creator {\n    public factoryMethod(): Product {\n        return new ConcreteProductB();\n    }\n}\n\n\u002F\u002F 使用示例\nconst creatorA = new ConcreteCreatorA();\nconsole.log(creatorA.someOperation()); \u002F\u002F \"Creator: The same creator's code has just worked with Result of ConcreteProductA\"\n```\n\n##### 1.3 抽象工厂模式 (Abstract Factory)\n\n提供一个接口，用于创建相关或依赖对象的家族，而无需明确指定具体类。\n\n```typescript\ninterface ProductA {\n    operationA(): string;\n}\n\ninterface ProductB {\n    operationB(): string;\n}\n\nclass ConcreteProductA1 implements ProductA {\n    public operationA(): string {\n        return 'Result of ConcreteProductA1';\n    }\n}\n\nclass ConcreteProductB1 implements ProductB {\n    public operationB(): string {\n        return 'Result of ConcreteProductB1';\n    }\n}\n\ninterface AbstractFactory {\n    createProductA(): ProductA;\n    createProductB(): ProductB;\n}\n\nclass ConcreteFactory1 implements AbstractFactory {\n    public createProductA(): ProductA {\n        return new ConcreteProductA1();\n    }\n\n    public createProductB(): ProductB {\n        return new ConcreteProductB1();\n    }\n}\n\n\u002F\u002F 使用示例\nconst factory = new ConcreteFactory1();\nconst productA = factory.createProductA();\nconst productB = factory.createProductB();\nconsole.log(productA.operationA()); \u002F\u002F \"Result of ConcreteProductA1\"\nconsole.log(productB.operationB()); \u002F\u002F \"Result of ConcreteProductB1\"\n```\n\n#### 2. 结构型模式\n\n##### 2.1 适配器模式 (Adapter)\n\n将一个类的接口转换成客户端所期望的另一种接口。\n\n```typescript\nclass Target {\n    public request(): string {\n        return 'Target: The default target\\'s behavior.';\n    }\n}\n\nclass Adaptee {\n    public specificRequest(): string {\n        return 'Adaptee: The specific behavior.';\n    }\n}\n\nclass Adapter extends Target {\n    private adaptee: Adaptee;\n\n    constructor(adaptee: Adaptee) {\n        super();\n        this.adaptee = adaptee;\n    }\n\n    public request(): string {\n        return `Adapter: (TRANSLATED) ${this.adaptee.specificRequest()}`;\n    }\n}\n\n\u002F\u002F 使用示例\nconst adaptee = new Adaptee();\nconst adapter = new Adapter(adaptee);\nconsole.log(adapter.request()); \u002F\u002F \"Adapter: (TRANSLATED) Adaptee: The specific behavior.\"\n```\n\n##### 2.2 装饰者模式 (Decorator)\n\n动态地给一个对象添加一些额外的职责。\n\n```typescript\ninterface Component {\n    operation(): string;\n}\n\nclass ConcreteComponent implements Component {\n    public operation(): string {\n        return 'ConcreteComponent';\n    }\n}\n\nclass Decorator implements Component {\n    protected component: Component;\n\n    constructor(component: Component) {\n        this.component = component;\n    }\n\n    public operation(): string {\n        return this.component.operation();\n    }\n}\n\nclass ConcreteDecoratorA extends Decorator {\n    public operation(): string {\n        return `ConcreteDecoratorA(${super.operation()})`;\n    }\n}\n\n\u002F\u002F 使用示例\nconst simple = new ConcreteComponent();\nconsole.log(simple.operation()); \u002F\u002F \"ConcreteComponent\"\n\nconst decorated = new ConcreteDecoratorA(simple);\nconsole.log(decorated.operation()); \u002F\u002F \"ConcreteDecoratorA(ConcreteComponent)\"\n```\n\n#### 3. 行为型模式\n\n##### 3.1 策略模式 (Strategy)\n\n定义一系列算法，将它们一个个封装起来，并使它们可以互相替换。\n\n```typescript\ninterface Strategy {\n    doAlgorithm(data: string[]): string[];\n}\n\nclass ConcreteStrategyA implements Strategy {\n    public doAlgorithm(data: string[]): string[] {\n        return data.sort();\n    }\n}\n\nclass ConcreteStrategyB implements Strategy {\n    public doAlgorithm(data: string[]): string[] {\n        return data.reverse();\n    }\n}\n\nclass Context {\n    private strategy: Strategy;\n\n    constructor(strategy: Strategy) {\n        this.strategy = strategy;\n    }\n\n    public setStrategy(strategy: Strategy): void {\n        this.strategy = strategy;\n    }\n\n    public doSomeBusinessLogic(): void {\n        const result = this.strategy.doAlgorithm(['a', 'b', 'c']);\n        console.log(result);\n    }\n}\n\n\u002F\u002F 使用示例\nconst context = new Context(new ConcreteStrategyA());\ncontext.doSomeBusinessLogic(); \u002F\u002F [\"a\", \"b\", \"c\"]\n\ncontext.setStrategy(new ConcreteStrategyB());\ncontext.doSomeBusinessLogic(); \u002F\u002F [\"c\", \"b\", \"a\"]\n```\n\n##### 3.2 观察者模式 (Observer)\n\n定义对象间的一种一对多依赖关系，以便当一个对象状态改变时，所有依赖于它的对象都得到通知并自动更新。\n\n```typescript\ninterface Observer {\n    update(subject: Subject): void;\n}\n\ninterface Subject {\n    attach(observer: Observer): void;\n    detach(observer: Observer): void;\n    notify(): void;\n}\n\nclass ConcreteSubject implements Subject {\n    private observers: Observer[] = [];\n    private state: number;\n\n    public attach(observer: Observer): void {\n        this.observers.push(observer);\n    }\n\n    public detach(observer: Observer): void {\n        const index = this.observers.indexOf(observer);\n        this.observers.splice(index, 1);\n    }\n\n    public notify(): void {\n        for (const observer of this.observers) {\n            observer.update(this);\n        }\n    }\n\n    public getState(): number {\n        return this.state;\n    }\n\n    public setState(state: number): void {\n        this.state = state;\n        this.notify();\n    }\n}\n\nclass ConcreteObserverA implements Observer {\n    public update(subject: Subject): void {\n        console.log(`ConcreteObserverA: Reacted to the event. New state: ${subject.getState()}`);\n    }\n}\n\n\u002F\u002F 使用示例\nconst subject = new ConcreteSubject();\nconst observerA = new ConcreteObserverA();\nsubject.attach(observerA);\nsubject.setState(1); \u002F\u002F \"ConcreteObserverA: Reacted to the event. New state: 1\"\n```\n\n### 不常用设计模式\n\n##### 4.1 责任链模式 (Chain of Responsibility)\n\n通过将请求的发送者和接收者解耦，形成一条处理请求的责任链。\n\n```typescript\nabstract class Handler {\n    protected successor: Handler;\n\n    public setSuccessor(successor: Handler): void {\n        this.successor = successor;\n    }\n\n    public abstract handleRequest(request: number): void;\n}\n\nclass ConcreteHandlerA extends Handler {\n    public handleRequest(request: number): void {\n        if (request \u003C 10) {\n            console.log(`Handler A handled request ${request}`);\n        } else if (this.successor) {\n            this.successor.handleRequest(request);\n        }\n    }\n}\n\nclass ConcreteHandlerB extends Handler {\n    public handleRequest(request: number): void {\n        if (request \u003C 20) {\n            console.log(`Handler B handled request ${request}`);\n        } else if (this.successor) {\n            this.successor.handleRequest(request);\n        }\n    }\n}\n\n\u002F\u002F 使用示例\nconst handlerA = new ConcreteHandlerA();\nconst handlerB = new ConcreteHandlerB();\nhandlerA.setSuccessor(handlerB);\n\nhandlerA.handleRequest(5);  \u002F\u002F \"Handler A handled request 5\"\nhandlerA.handleRequest(15); \u002F\u002F \"Handler B handled request 15\"\n```\n\n##### 4.2 状态模式 (State)\n\n允许对象在内部状态改变时改变其行为。\n\n```typescript\ninterface State {\n    handle(context: Context): void;\n}\n\nclass ConcreteStateA implements State {\n    public handle(context: Context): void {\n        console.log('Handling request in State A');\n        context.setState(new ConcreteStateB());\n    }\n}\n\nclass ConcreteStateB implements State {\n    public handle(context: Context): void {\n        console.log('Handling request in State B');\n        context.setState(new ConcreteStateA());\n    }\n}\n\nclass Context {\n    private state: State;\n\n    constructor(state: State) {\n        this.setState(state);\n    }\n\n    public setState(state: State): void {\n        this.state = state;\n    }\n\n    public request(): void {\n        this.state.handle(this);\n    }\n}\n\n\u002F\u002F 使用示例\nconst context = new Context(new ConcreteStateA());\ncontext.request\n\n(); \u002F\u002F \"Handling request in State A\"\ncontext.request(); \u002F\u002F \"Handling request in State B\"\n```\n\n### 总结\n\n以上展示了多种设计模式在 TypeScript 中的实现，包括常用和不常用的模式。这些模式为代码的组织和结构提供了灵活性，增强了可维护性和可扩展性。掌握这些设计模式，可以帮助开发者在实际开发中更好地解决问题，提高代码质量。\n",{"id":118,"created_at":119,"updated_at":119,"code":120,"author_id":7,"book_id":4,"slug":121,"article_id":122,"title":123,"sort_order":118,"content":124,"status":12},144,"2024-10-06T07:57:20.797+08:00","1xXEG06a","最佳实践-144",557,"最佳实践","### TypeScript 最佳实践\n\n在 TypeScript 开发中，遵循最佳实践可以显著提高代码质量、可维护性和性能。以下是关于代码风格与约定、性能优化以及代码维护与重构的详细说明。\n\n#### 1. 代码风格与约定\n\n##### 1.1 一致的编码风格\n\n- **使用 TypeScript 的类型系统**：\n\n  - 始终为函数和变量定义明确的类型，以便在编译时捕获错误。\n\n    ```typescript\n    function add(a: number, b: number): number {\n        return a + b;\n    }\n    ```\n- **命名约定**：\n\n  - 使用一致的命名规则（如 camelCase、PascalCase 等）来提高可读性。\n  - 类名使用 PascalCase，接口名以 \"I\" 开头。\n\n    ```typescript\n    interface IUser {\n        id: number;\n        name: string;\n    }\n    class User implements IUser {\n        \u002F\u002F ...\n    }\n    ```\n- **文件组织**：\n\n  - 按照功能或模块组织代码，使用文件夹分隔不同的模块或功能。\n\n    ```\n    src\u002F\n    ├── components\u002F\n    ├── services\u002F\n    ├── utils\u002F\n    └── types\u002F\n    ```\n\n##### 1.2 使用 ESLint 和 Prettier\n\n- **ESLint**：\n\n  - 使用 ESLint 检查代码中的语法和风格问题。可以与 TypeScript 一起使用。\n\n    ```bash\n    npm install --save-dev eslint @typescript-eslint\u002Fparser @typescript-eslint\u002Feslint-plugin\n    ```\n  - 配置 `.eslintrc.js` 文件：\n\n    ```javascript\n    module.exports = {\n        parser: '@typescript-eslint\u002Fparser',\n        plugins: ['@typescript-eslint'],\n        extends: ['plugin:@typescript-eslint\u002Frecommended'],\n    };\n    ```\n- **Prettier**：\n\n  - 使用 Prettier 格式化代码，确保代码一致性。\n\n    ```bash\n    npm install --save-dev prettier\n    ```\n  - 配置 `.prettierrc` 文件：\n\n    ```json\n    {\n        \"semi\": true,\n        \"singleQuote\": true,\n        \"tabWidth\": 4,\n        \"trailingComma\": \"all\"\n    }\n    ```\n\n#### 2. 性能优化\n\n##### 2.1 减少编译时间\n\n- **使用增量编译**：\n\n  - 在 `tsconfig.json` 中启用 `incremental` 选项，使用缓存加速编译。\n\n    ```json\n    {\n        \"compilerOptions\": {\n            \"incremental\": true\n        }\n    }\n    ```\n- **拆分项目**：\n\n  - 将大型项目拆分成多个小型项目，使用 Project References 来管理。\n\n##### 2.2 代码优化\n\n- **避免不必要的类型断言**：\n\n  - 避免过多的类型断言，保持类型安全性。\n\n    ```typescript\n    \u002F\u002F 不推荐\n    const value = someValue as string;\n\n    \u002F\u002F 推荐\n    if (typeof someValue === 'string') {\n        const value: string = someValue;\n    }\n    ```\n- **使用懒加载**：\n\n  - 对于大型组件或模块，使用懒加载技术，提高初始加载速度。\n\n    ```typescript\n    const LazyComponent = React.lazy(() => import('.\u002FLazyComponent'));\n    ```\n- **避免不必要的对象创建**：\n\n  - 在循环中避免创建新的对象，复用现有对象。\n\n##### 2.3 使用合适的数据结构\n\n- **选择合适的数据结构**：\n  - 根据使用场景选择合适的数据结构，减少内存消耗和提高性能。\n\n    ```typescript\n    const set = new Set\u003Cnumber>();\n    set.add(1);\n    set.has(1); \u002F\u002F O(1) 查找\n    ```\n\n#### 3. 代码维护与重构\n\n##### 3.1 代码可读性\n\n- **注释与文档**：\n\n  - 适当使用注释和文档说明复杂的业务逻辑和关键代码。\n\n    ```typescript\n    \u002F**\n     * 计算两个数字的和\n     * @param a 第一个数字\n     * @param b 第二个数字\n     * @returns 两个数字的和\n     *\u002F\n    function add(a: number, b: number): number {\n        return a + b;\n    }\n    ```\n- **避免复杂的函数**：\n\n  - 每个函数应只完成一项任务，保持函数简短，避免过多的嵌套。\n\n    ```typescript\n    \u002F\u002F 不推荐\n    function process(data: any) {\n        \u002F\u002F ... 复杂逻辑\n    }\n\n    \u002F\u002F 推荐\n    function validateData(data: any): boolean {\n        \u002F\u002F ... 验证逻辑\n    }\n\n    function processData(data: any) {\n        if (!validateData(data)) return;\n        \u002F\u002F ... 处理逻辑\n    }\n    ```\n\n##### 3.2 重构策略\n\n- **逐步重构**：\n\n  - 遇到复杂代码时，不要一次性重构，分步骤进行，确保每一步都能通过测试。\n- **使用测试驱动开发 (TDD)**：\n\n  - 在重构前编写单元测试，确保重构后功能不受影响。\n\n    ```bash\n    npm install --save-dev jest ts-jest @types\u002Fjest\n    ```\n- **保持功能完整性**：\n\n  - 在重构时，保持原有功能不变，避免引入新功能导致风险。\n\n##### 3.3 使用设计模式\n\n- **采用合适的设计模式**：\n  - 根据需求选择合适的设计模式，优化代码结构和可扩展性。\n\n    ```typescript\n    \u002F\u002F 例如使用单例模式\n    class Config {\n        private static instance: Config;\n\n        private constructor() {}\n\n        public static getInstance(): Config {\n            if (!Config.instance) {\n                Config.instance = new Config();\n            }\n            return Config.instance;\n        }\n    }\n    ```\n\n### 总结\n\n遵循 TypeScript 的最佳实践有助于提高代码的可维护性、可读性和性能。通过一致的代码风格、有效的性能优化策略，以及良好的代码维护和重构方法，可以确保项目的长期成功。在实际开发中，结合团队的具体需求和项目的特点，灵活应用这些最佳实践，将会获得更好的效果。\n",{"id":126,"created_at":127,"updated_at":127,"code":128,"author_id":7,"book_id":4,"slug":129,"article_id":130,"title":131,"sort_order":126,"content":132,"status":12},145,"2024-10-06T07:58:15.233+08:00","Mg87YdKG","项目实践-145",558,"项目实践","### TypeScript 项目实践：待办事项应用（Todo App）\n\n本项目是一个简单的待办事项应用，使用 TypeScript 和 React 构建，支持添加、删除和标记待办事项。下面将详细介绍项目的功能、步骤和完整代码。\n\n#### 1. 功能介绍\n\n- **添加待办事项**：用户可以输入待办事项并添加到列表中。\n- **删除待办事项**：用户可以删除已完成或不再需要的待办事项。\n- **标记待办事项**：用户可以标记待办事项为完成状态。\n- **存储待办事项**：使用 Local Storage 保存待办事项，使其在页面刷新后仍然可用。\n\n#### 2. 项目步骤\n\n##### 2.1 创建项目\n\n1. **初始化项目**：\n\n   ```bash\n   npx create-react-app todo-app --template typescript\n   cd todo-app\n   ```\n2. **安装依赖**：\n\n   ```bash\n   npm install uuid\n   ```\n\n##### 2.2 项目结构\n\n```plaintext\ntodo-app\u002F\n├── public\u002F\n├── src\u002F\n│   ├── components\u002F\n│   │   ├── TodoItem.tsx\n│   │   └── TodoList.tsx\n│   ├── App.tsx\n│   ├── index.tsx\n│   ├── styles.css\n│   └── types.ts\n├── package.json\n└── tsconfig.json\n```\n\n##### 2.3 创建类型定义\n\n创建 `src\u002Ftypes.ts` 文件：\n\n```typescript\nexport interface Todo {\n    id: string;\n    text: string;\n    completed: boolean;\n}\n```\n\n##### 2.4 创建待办事项项组件\n\n创建 `src\u002Fcomponents\u002FTodoItem.tsx` 文件：\n\n```typescript\nimport React from 'react';\nimport { Todo } from '..\u002Ftypes';\n\ninterface TodoItemProps {\n    todo: Todo;\n    onToggle: (id: string) => void;\n    onDelete: (id: string) => void;\n}\n\nconst TodoItem: React.FC\u003CTodoItemProps> = ({ todo, onToggle, onDelete }) => {\n    return (\n        \u003Cdiv style={{ display: 'flex', alignItems: 'center' }}>\n            \u003Cinput\n                type=\"checkbox\"\n                checked={todo.completed}\n                onChange={() => onToggle(todo.id)}\n            \u002F>\n            \u003Cspan\n                style={{\n                    textDecoration: todo.completed ? 'line-through' : 'none',\n                    marginLeft: '8px',\n                }}\n            >\n                {todo.text}\n            \u003C\u002Fspan>\n            \u003Cbutton onClick={() => onDelete(todo.id)} style={{ marginLeft: '8px' }}>\n                Delete\n            \u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n    );\n};\n\nexport default TodoItem;\n```\n\n##### 2.5 创建待办事项列表组件\n\n创建 `src\u002Fcomponents\u002FTodoList.tsx` 文件：\n\n```typescript\nimport React from 'react';\nimport { Todo } from '..\u002Ftypes';\nimport TodoItem from '.\u002FTodoItem';\n\ninterface TodoListProps {\n    todos: Todo[];\n    onToggle: (id: string) => void;\n    onDelete: (id: string) => void;\n}\n\nconst TodoList: React.FC\u003CTodoListProps> = ({ todos, onToggle, onDelete }) => {\n    return (\n        \u003Cdiv>\n            {todos.map(todo => (\n                \u003CTodoItem\n                    key={todo.id}\n                    todo={todo}\n                    onToggle={onToggle}\n                    onDelete={onDelete}\n                \u002F>\n            ))}\n        \u003C\u002Fdiv>\n    );\n};\n\nexport default TodoList;\n```\n\n##### 2.6 创建主应用组件\n\n修改 `src\u002FApp.tsx` 文件：\n\n```typescript\nimport React, { useState, useEffect } from 'react';\nimport { Todo } from '.\u002Ftypes';\nimport TodoList from '.\u002Fcomponents\u002FTodoList';\n\nconst App: React.FC = () => {\n    const [todos, setTodos] = useState\u003CTodo[]>([]);\n    const [newTodo, setNewTodo] = useState\u003Cstring>('');\n\n    useEffect(() => {\n        const storedTodos = localStorage.getItem('todos');\n        if (storedTodos) {\n            setTodos(JSON.parse(storedTodos));\n        }\n    }, []);\n\n    useEffect(() => {\n        localStorage.setItem('todos', JSON.stringify(todos));\n    }, [todos]);\n\n    const addTodo = () => {\n        if (!newTodo) return;\n\n        const todo: Todo = {\n            id: Date.now().toString(),\n            text: newTodo,\n            completed: false,\n        };\n\n        setTodos([...todos, todo]);\n        setNewTodo('');\n    };\n\n    const toggleTodo = (id: string) => {\n        setTodos(todos.map(todo => (todo.id === id ? { ...todo, completed: !todo.completed } : todo)));\n    };\n\n    const deleteTodo = (id: string) => {\n        setTodos(todos.filter(todo => todo.id !== id));\n    };\n\n    return (\n        \u003Cdiv style={{ padding: '20px' }}>\n            \u003Ch1>Todo App\u003C\u002Fh1>\n            \u003Cinput\n                type=\"text\"\n                value={newTodo}\n                onChange={e => setNewTodo(e.target.value)}\n                placeholder=\"Add a new todo\"\n            \u002F>\n            \u003Cbutton onClick={addTodo}>Add Todo\u003C\u002Fbutton>\n            \u003CTodoList todos={todos} onToggle={toggleTodo} onDelete={deleteTodo} \u002F>\n        \u003C\u002Fdiv>\n    );\n};\n\nexport default App;\n```\n\n##### 2.7 添加样式\n\n创建或修改 `src\u002Fstyles.css` 文件（可选）：\n\n```css\nbody {\n    font-family: Arial, sans-serif;\n}\n\ninput {\n    margin-right: 8px;\n}\n```\n\n在 `src\u002Findex.tsx` 文件中引入样式：\n\n```typescript\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport '.\u002Fstyles.css'; \u002F\u002F 引入样式\nimport App from '.\u002FApp';\n\nReactDOM.render(\n    \u003CReact.StrictMode>\n        \u003CApp \u002F>\n    \u003C\u002FReact.StrictMode>,\n    document.getElementById('root')\n);\n```\n\n##### 2.8 运行应用\n\n在项目目录中运行以下命令启动应用：\n\n```bash\nnpm start\n```\n\n### 3. 项目测试与展示\n\n#### 3.1 使用方式\n\n- 打开浏览器，访问 `http:\u002F\u002Flocalhost:3000`。\n- 在输入框中输入待办事项并点击“Add Todo”按钮。\n- 使用复选框标记待办事项为完成或未完成。\n- 点击“Delete”按钮删除待办事项。\n- 页面刷新后，待办事项会自动从 Local Storage 中恢复。\n\n#### 3.2 代码总结\n\n这个简单的待办事项应用展示了如何使用 TypeScript 和 React 构建一个基本的功能应用。通过管理状态、处理用户输入以及持久化数据，我们实现了一个完整的待办事项管理工具。该项目可以作为更复杂项目的基础，进一步扩展功能，如编辑待办事项、分类、过滤等。\n\n### 4. 项目扩展\n\n- **用户认证**：可以添加用户注册和登录功能，使用 Firebase 或其他后端服务。\n- **多用户支持**：实现多用户的待办事项管理。\n- **拖放功能**：使用库如 `react-beautiful-dnd` 增加拖放排序功能。\n- **样式优化**：使用 CSS 框架如 Bootstrap 或 Material-UI 提升用户界面。\n\n以上是完整的 TypeScript 项目实践，适合入门和提升开发者的技能。希望能对你有所帮助！\n",{"id":70,"created_at":71,"updated_at":71,"code":72,"author_id":7,"book_id":4,"slug":73,"article_id":74,"title":75,"sort_order":70,"content":76,"status":12}]