TypeScript入門筆記(二)

上篇html

TypeSrcipt 泛型

  1 /*---------------------------------0.引子-----------------------------------*/
  2 /*如今不少語言裏也有泛型的概念,也沒啥好說的,簡單的例子一個,主要就是看泛型在ts中的寫法*/
  3 function getInfo<T>(params: T): T {
  4     return params;
  5 }
  6 //調用泛型方法
  7 let output_str = getInfo<string>("str");
  8 //簡單的寫法:並且ts的編譯器可以自動幫咱們推斷類型
  9 let output_num = getInfo(100);
 10 /*--------------------------------------------------------------------------*/
 11 
 12 /*--------------------------------1.泛型參數---------------------------------*/
 13 //方法參數使用泛型,類型是指定類型的數組
 14 function getMax<T>(arr: Array<T>): T {
 15     let max = arr[0];
 16     arr.forEach(item => {
 17         if (item > max) {
 18             max = item;
 19         }
 20     });
 21     return max;
 22 }
 23 let numArr: Array<number> = [2, 3, 44, 1, 9, 10];
 24 let numStr: Array<string> = ['c', 'd', 'a', 'A'];
 25 
 26 console.log(getMax(numArr));    //44
 27 console.log(getMax(numStr));    //d
 28 /*--------------------------------------------------------------------------*/
 29 
 30 /*--------------------------------2.泛型接口----------------------------------*/
 31 //在ts中就不要使用I作爲接口名前綴了,這不是人家的規範
 32 interface GetMinFn {
 33     <T>(arg: Array<T>): T
 34 }
 35 /* 其實我更喜歡這麼寫
 36 interface GetMin<T> {
 37     (arg: Array<T>): T
 38 }
 39 */
 40 
 41 //寫一個方法
 42 function getMin<T>(arr: Array<T>): T {
 43     let min = arr[0];
 44     arr.forEach(item => {
 45         if (item < min) {
 46             min = item;
 47         }
 48     });
 49     return min;
 50 }
 51 //用接口來接方法
 52 let myGetMinFunction: GetMinFn = getMin;
 53 console.log(myGetMinFunction(numArr));    //1
 54 /*--------------------------------------------------------------------------*/
 55 
 56 /*--------------------------------3.泛型類-----------------------------------*/
 57 //跟泛型接口大差不差
 58 class MySort<T>{
 59     private dataCollection: Array<T> = new Array<T>();
 60 
 61     constructor(arr?: Array<T>) {
 62         if (arr) {
 63             this.dataCollection = arr;
 64         }
 65     }
 66 
 67     add(data: T): void {
 68         this.dataCollection.push(data);
 69     }
 70 
 71     min(): T {
 72         return getMin<T>(this.dataCollection);
 73     }
 74 
 75     max(): T {
 76         return getMax<T>(this.dataCollection);
 77     }
 78 }
 79 //實例化泛型類,須要傳入類型參數
 80 let numberSortObj = new MySort<number>(numArr);
 81 let stringSortObj = new MySort<string>(numStr);
 82 
 83 console.log(numberSortObj.min());   //1
 84 console.log(numberSortObj.max());   //44
 85 console.log(stringSortObj.min());   //A
 86 console.log(stringSortObj.max());   //d
 87 /*--------------------------------------------------------------------------*/
 88 
 89 /*--------------------------------4.泛型約束---------------------------------*/
 90 //就是T表明的類型不是全部類型均可以的,須要知足必定的條件,這個條件就稱爲「泛型約束」
 91 //好比下面的函數,想獲取傳入的變量的長度,可是不是全部的類型都有「長度」這個屬性的
 92 // function getLength<T>(arg: T): T {
 93 //     console.log(arg.length);  // Error: T必定就有".length"這個屬性
 94 //     return arg;
 95 // }
 96 
 97 interface Lengthwise {
 98     length: number;
 99 }
100 //傳入的參數必須知足接口 Lengthwise 的約束,約束就是必須有一個名爲length的屬性,而且返回
101 //值是number類型
102 function getLength<T extends Lengthwise>(arg: T): T {
103     console.log(arg.length);  // OK
104     return arg;
105 }
106 
107 //如今這個泛型方法傳入的參數類型就獲得了約束
108 //getLength(3);   //Error:Argument of type '3' is not assignable to parameter
109                 //of type 'Lengthwise'.
110 getLength([1, 2, 3, 4, 5]);             //5
111 getLength({ length: 10, value: 3 });    //10
112 
113 /*--------------------------------------------------------------------------*/

TypeSrcipt 類型兼容性

 1 //類型兼容性的話咱們在其餘語言(C#或者Java)中也都接觸過,舉幾個典型例子
 2 
 3 /********************************1. 「接口」接收「類」*******************************/
 4 interface Named {
 5     name: string;
 6 }
 7 
 8 class People {
 9     name: string;
10     constructor(n: string) {
11         this.name = n;
12     }
13 }
14 
15 let p: Named = new People("sherlock");
16 
17 //****2. "接口"接收對象,只要包含name屬性便可,編譯器檢查的過程是遞歸進行的,檢查每一個成員及子成員。****
18 //****因此說TypeScript是結構性的類型系統,咱對比兩個類型是否相同就看你的內部結構是否同樣*************
19 let alice: Named;
20 let aliceProfile = { name: 'Alice', location: 'Seattle' };
21 //變量aliceProfile中包含name屬性
22 alice = aliceProfile;
23 
24 //********************************3. 同上,方法參數也能夠是接口********************************
25 function sayHello(n: Named) {
26     console.log('Hello, i am ', n.name);
27 }
28 sayHello(aliceProfile);
29 
30 //********4. 比較兩個函數,強類型語言中不多有這樣的寫法,可是在js中函數也是一種特殊對象,****************
31 //********這樣就好理解了,你能夠對比到子類型和父類型
32 let a = (a: number) => 0;
33 let b = (b: number, s: string) => 0;
34 
35 a = b; // 報錯
36 b = a; // OK
37 
38 let c = () => ({ name: 'Alice' });
39 let d = () => ({ name: 'Alice', location: 'Seattle' });
40 
41 c = d; // OK
42 d = c; // 報錯, 系統強制源函數的返回值類型必須是目標函數返回值類型的子類型
43 
44 
45 //********************************5. 不一樣的枚舉類型之間是不兼容的********************************
46 enum Status { Ready, Waiting };
47 enum Color { Red, Blue, Green };
48 
49 let s = Status.Ready;
50 s = Color.Green;  // Error
51 
52 //********6. 比較兩個類類型的對象時,只有實例的成員會被比較。 靜態成員和構造函數不在比較的範圍內***********
53 //********而且變量的可訪問等級也要是相同的
54 class Beauty {
55     eyes: number = 2;
56     constructor(name: string, height: number) { }
57 }
58 
59 class Ugly {
60     eyes: number = 2;
61     constructor(height: number) { }
62 }
63 
64 let jack: Beauty = new Beauty("jack", 190);
65 let jordan: Ugly = new Ugly(140);
66 
67 jack = jordan;  // OK
68 jordan = jack;  // OK
69 
70 //********************************7. 再看一下泛型*********************************************
71 interface Empty<T> {
72 }
73 
74 let eNum: Empty<number>;
75 let eStr: Empty<string>;
76 
77 eNum = eStr;  // OK, 由於Empty<T>這個接口中的「結構」都是空的,因此這兩個就是兼容的
78 
79 interface NotEmpty<T> {
80     data: T;
81 }
82 let neNum: NotEmpty<number>;
83 let neStr: NotEmpty<string>;
84 
85 neNum = neStr;  // Error, 這種狀況下兩個對象中的「結構」一個是number型一個是string,就不一樣了
相關文章
相關標籤/搜索