好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

TypeScript入门笔记(二)

接 上篇 。

   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,就不同了 

 

查看更多关于TypeScript入门笔记(二)的详细内容...

  阅读:39次