刘聪 3 年 前
コミット
b77beb8352
2 ファイル変更206 行追加1 行削除
  1. BIN
      TS/Image/24.png
  2. 206 1
      TS/Typescript.md

BIN
TS/Image/24.png


+ 206 - 1
TS/Typescript.md

@@ -1029,7 +1029,7 @@ interface IFoo{
     age: number
 }
 
-const foo: IFoo = {
+onst foo: IFoo = {
     name : "x",
     age : 10
 }  
@@ -1087,3 +1087,208 @@ typescript会对`{name: "why",age: 19,height: 198,address: "BJ"}`进行类型推
 
 ## 泛型
 
+**为了让代码具有很强的可重用性**
+
+在定义函数的时候,不决定参数的类型,而是让调用者以参数的形式决定函数参数应该是什么类型  
+
+```typescript
+function sum2<Type>(num1 : Type, num2: Type){
+    return num1 + num2; // Error Type不一定是可以相加的类型 比如数组
+}
+
+function sum<Type>(num1: Type, num2: Type){
+    return num1;
+}
+function sum1<Type>(num1: Type){
+    return num1;
+}
+console.log(typeof sum<number>(20, 30) === 'number');
+
+// 1. 明确传入类型
+sum<number>(20, 30);
+sum<{name : string}>({name: "x"}, {name: "y"});
+sum<any[]>([20], [30]);
+
+// 2. 类型推导
+sum1(40);
+```
+
+![类型推导](./Image/24.png)
+
+> 类型推导出来`Type`是字面量类型,如果不想是字面量类型就需要`sum<number>(40)`明确指定类型  
+
+```typescript
+function foo<T, V>(arg1: T, arg2: V){
+    console.log(arg1, arg2);
+}
+foo<number, string>(10, "qwer");
+```
+
+### 泛型接口
+
+```typescript
+interface IPerson<T1, T2>{
+    name: T1,
+    age: T2
+}
+
+let p: IPerson<string, number> = {
+    name: "x",
+    age: 10
+}
+
+interface IStu<T1 = string, T2 = number>{
+    name: T1,
+    age: T2
+}
+
+let p2: IStu = {
+    name: "y",
+    age: 10
+}
+```
+
+> 泛型接口没有类型推导,所以必须写明类型,例:IPerson  
+> 可以使用默认类型,例:IStu  
+
+### 泛型类
+
+```typescript
+class Point<T>{
+    x: T;
+    y: T;
+    z: T;
+
+    constructor(x: T, y: T, z: T){
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+}
+
+let p0 = new Point<string>("1", "2", "3");
+// 类型推导
+const p = new Point("1", "2", "3");
+```
+
+> 泛型类可以类型推导
+
+### 泛型的类型约束
+
+```typescript
+// 使用联合类型
+function getLength(arg: string | any[]){
+    return arg.length;
+}
+
+interface ILength{
+    length: number
+}
+// 使用泛型
+function getLength1<Type extends ILength>(arg: Type){
+    return arg.length;
+}
+
+getLength1("abav");
+getLength1([1, 2, 3, 4]);
+getLength1({length: 100});
+```
+
+> 使用`extends`来限制Type的类型或者必须包含的属性等
+
+## 模块化
+
+```typescript
+// math.ts文件
+export function add(num1: number, num2: number){
+    return num1 + num2;
+}
+
+export function sub(num1: number, num2: number){
+    return num1 - num2;
+}
+
+// index.ts
+import {add, sub} from "./math"
+console.log(add(1, 2));
+console.log(sub(1, 2));
+```
+
+### 命名空间
+
+命名空间在typescript早期时,称之为内部模块,主要目的是将一个模块内部再进行作用域的划分,防止一些命名冲突的问题  
+
+```typescript
+namespace time {
+    export function format(time: string){
+        return "2022-1-1";
+    }
+
+    function foo(){
+
+    }
+
+    let name: string = "time"
+}
+namespace price {
+    export function format(price: number){
+        return "100,000,000";
+    }
+
+    function foo(){
+
+    }
+    let name: string = "price "
+}
+
+export namespace test{  // 导出命名空间
+    export function Run(){
+
+    }
+}
+
+time.format("1234");    // Success
+time.foo();             // Error
+time.name;              // Error
+
+// index.ts
+import {test} from './test.ts'  // 
+test.Run();
+```
+
+> 如果想要函数、自变量可以在命名空间的外部进行访问,需要将其设置为`export`
+
+### 类型的查找
+
+之前我们所有的typescript中的类型,几乎都是我们自己编写的,但是也有用过一些其他的类型  
+
+> `const imageEl = document.getElementById("image") as HTMLImageElement`
+
+上述代码中的`HTMLImageElement`我们没有进行定义或者声明,那么它是从哪里来的呢?  
+
+- Typescript对类型的**管理和查找规则**  
+
+之前编写的代码都是.ts文件中的,这些文件最终会输出成.js文件。除此之外,还有另一种.d.ts文件,他hi是用来做类型的声明(declare)。它仅仅是用来做类型检测,告知typescript有哪些类型  
+
+- TS会在这些地方查找类型声明
+  - 内置类型声明:安装typescript时自带的,包括Array等[TS内置类型(.d.ts文件))](https://github.com/microsoft/Typescript/tree/main/lib)
+  - 外部定义类型声明:安装的一些库,自带`.d.ts`文件,表示对三方库的类型声明
+    - 安装的三方库中自带`.d.ts`类型声明文件
+    - 安装的三方库,通过社区的公有库`DefinitelyTyped`存放类型声明文件
+      - [该库的地址](https://github.com/DefinitelyTyped/DefinitelyTyped)
+      - [该库查找声明安装方式的地址](https://www.typescriptlang.org/dt/search?search=)
+      - 比如安装react的类型声明:`npm io @types/react --save-dev`
+  - 自己定义类型声明
+    - 使用的第三方库是一个纯的Javascript库,没有对应的声明文件时,需要自己定义,比如:`lodash`
+    - 我们自己的代码中声明一些类型,方便在其他地方直接进行使用
+
+```typescript
+// 内置声明 HTMLImageElement 
+const imageEl = document.getElementById("image") as HTMLImageElement;
+
+// 自定义类型声明 
+// MyD.d.ts 自己声明lodash库
+declare module 'lodash' {
+    export function join(arr: any[]): void;
+}
+```