好得很程序员自学网

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

TypeScript入门笔记(一)

TypeScript是微软开发的一个JavaScript的超集,个人感觉就是基于Js之上增加更多强类型约束与检查机制,是一个严格模式模式下的严格Js(禁止套娃)。特别是对于熟悉后台开发的同志,很多地方都会触发共鸣(特别是C#开发者,毕竟TypeScript是微软推出的,当然会有亲儿子的影子)。但是在学习TypeScript之前呢,最好要有JavaScript和ES6知识的基础,不然磕磕碰碰的学会打消积极性的。废话少说,开始水博客,这里记录本人学习ts路上的一些笔记,本人主要是根据 官方文档 和 中文官网 一篇篇看下来的,中途无意间撞见 阮一峰大佬的 教程 觉得挺不错的,推荐想快速入门的同志们参考。

   1  console.log("TypeSrcipt 基本数据类型" );
    2   /* 
   3   基本数据类型
    4   */ 
   5  
   6   /*   ----------------------------------------------------------------------   */ 
   7   //  0. 布尔值 
   8  let isDone:  boolean  =  false  ;
    9  
  10   /*   ----------------------------------------------------------------------   */ 
  11   //  1. 数字类型 
  12  let age: number = 28 ;
   13   //  二进制表示法: 
  14  let binaryLiteral: number =  0b1010;
   15   //  八进制表示法: 
  16  let octalLiteral: number =  0o732;
   17  
  18   /*   ----------------------------------------------------------------------   */ 
  19   //  2. 字符串 
  20  let fname: string = "Alice" ;
   21   //   模板字符串 
  22  let greet: string =  `Hello ,my name is ${fname}, i am ${age} years old`;
   23  console.log("string类型:" , greet);
   24  
  25   /*   ----------------------------------------------------------------------   */ 
  26   //  3. 数组类型 
  27   //  使用「类型 + 方括号」来表示数组 
  28  let list1: number[] = [1, 2, 3, 4, 5 ];
   29  console.log("数组类型1 :" , list1);
   30  
  31   //  使用数组泛型(Array Generic) Array<elemType> 来表示数组 
  32  let list2: Array<string> = ["Alice", "Bob", "John" ];
   33  console.log("数组类型2 :" , list2);
   34  
  35  list1.push(6);   //  添加元素 
  36  list1.pop();     //  弹出元素 
  37  console.log("按索引访问:list1[2]:", list1[2 ])
   38  
  39   //  用 any 表示数组中允许出现任意类型 
  40  let list3: any[] = ['xcatliu', 25, { website: 'http://xcatliu.com'  }];
   41  
  42   /*   ----------------------------------------------------------------------   */ 
  43   //  4. 元组类型 
  44   //  类似C#中的Tuple类型 
  45   let card: [string, number];
   46  card =  [fname, age];
   47  console.log("元组类型:" , card);
   48  console.log("元组可按索引访问 card[0]:", card[0 ]);
   49  console.log("元组可按索引访问 card[1]:", card[1 ]);
   50   /* 
  51   下面这个写法ts会报错,但是js可以通过并且正常运行
   52   card[3] = 'world';
   53   console.log("元组类型:", card);
   54   */ 
  55  
  56   //  当添加越界的元素时,它的类型会被限制为元组中每个类型的联合类型: 
  57   let tom1: [string, number];
   58  tom1 = ['Tom', 25 ];
   59  tom1.push('male' );
   60   //  tom1.push(true); 
  61  console.log("元组类型2:" , tom1);
   62  
  63   /*   -----------------------------------------------------------------------   */ 
  64   //  5. 枚举类型 
  65   enum Gender {
   66      Female = 0 ,
   67       Male
   68   }
   69  let gender: Gender =  Gender.Female;
   70  console.log("枚举类型 gender:" , gender);
   71  console.log("gender === 0 :", gender === 0);   //  true 
  72  console.log(<number>Gender.Female + 1);  //  1 
  73  
  74   enum SeatLevel {
   75      LevelI = "一等座" ,
   76      LevelII = "二等座" ,
   77      LevelIII = "站票"
  78   }
   79  let myTicket =  SeatLevel.LevelIII;
   80  console.log("myTicket === 站票 :", myTicket === "站票");   //  true 
  81   //  console.log("myTicket == 一等座 :", myTicket == "一等座");  //false 
  82  
  83   /*   -----------------------------------------------------------------------   */ 
  84   //  6. Any类型 
  85   //  Any类型允许赋值为任意类型 
  86  let file: any = 123456789 ;
   87   console.log(file);
   88  file = "Quis labore excepteur aliqua aliquip."
  89   console.log(file);
   90  file =  false  ;
   91   console.log(file);
   92   //  在any类型上访问任何属性和任何方法都是允许的 
  93   //  file.ifItExistProp; // okay, ifItExistProp might exist at runtime 
  94   //  file.ifItExists();  // okay, ifItExists might exist at runtime 
  95   //  file.toFixed();     // okay, toFixed exists (but the compiler doesn't check) 
  96  let repo: any[] = [1, "Nisi reprehenderit qui irure dolor sunt culpa occaecat.",  false  ];
   97  console.log("any数组类型,repo[1]: ", repo[1 ]);
   98  
  99   //  联合类型:表示取值可以为多种类型中的一种 
 100  let numberOrString: string |  number;
  101  numberOrString = 'seven' ;
  102  console.log(numberOrString.length);  //   5 
 103  
 104  numberOrString = 7 ;
  105   //  console.log(numberOrString.length); // 编译时报错:Property 'length' does not exist on type 'number' 
 106  
 107   /*   -----------------------------------------------------------------------   */ 
 108   //  7. void类型 
 109   function  warnUser():  void   {
  110      console.log("This is my warning message" );
  111   }
  112   //  声明一个void类型的变量没有什么大用,因为你只能为它赋予undefined和null 
 113  let unusable:  void  =  undefined;
  114  
 115   /*   -----------------------------------------------------------------------   */ 
 116   /*  8. nerver类型:表示的是那些永不存在的值的类型
  117     never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式的返回值类型
  118     下面3个函数为常见的返回值类型为never的函数  */ 
 119   //  (1)无法达到的终点的函数返回类型是 never 
 120   function   infiniteLoop(): never {
  121       while  ( true  ) {
  122       }
  123   }
  124   //  (2)抛出异常的函数也是一种无法到达“终点”的函数,所以返回类型也是 never 
 125   function   error(message: string): never {
  126       throw   new   Error(message);
  127   }
  128   //  (3)智能推断的返回值类型为never 
 129   function   fail() {
  130       return  error("Something failed" );
  131   }
  132  
 133   /*   -----------------------------------------------------------------------   */ 
 134   /*  9. object 类型
  135       object表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型。
  136   */ 
 137  let person: object =  {
  138       fname: fname,
  139       age: age,
  140       gender: gender,
  141       card: card
  142   }
  143   function  Greet(p: object |  null ):  void   {
  144       if  (p ==  null  ) {
  145          console.log("Hello everyone!" );
  146       }
  147       //   let name = p.fname; 
 148       //   let age = p.age; 
 149       //   console.log(`Hello ,my name is ${name}, i am ${age} years old`); 
 150   };
  151  Greet( null  );
  152   Greet(person);
  153   //   Greet(fname);  //报错 
 154  
 155   /*   -----------------------------------------------------------------------   */ 
 156   /*  10. 类型断言,类似与其他语言中的强制类型转换   */ 
 157  let someValue: any = "this is a string" ;
  158   //  写法一: 
 159  let strLength: number = (<string> someValue).length;
  160  console.log("strLength:" , strLength);
  161   //  写法二:用as 
 162  strLength =  (someValue as string).length;
  163  console.log("strLength:", strLength);

TypeSrcipt 函数

  1   /*  ------------------------------1.函数声明----------------------------------  */ 
  2   //  1.1 为函数定义类型 
  3   function add(x: number, y: number): number {
   4       return  x +  y;
   5   }
   6  let myAdd =  function (x: number, y: number): number {
   7       return  x +  y;
   8   }
   9  let myAddFunc = (x: number, y: number): number => x +  y;
  10  
 11  let [x, y] = [ 1 ,  2  ];
  12  console.log(`add : ${x} + ${y} =  `, add(x, y));
  13  console.log(`myAdd: ${x} + ${y} =  `, myAdd(x, y));
  14  console.log(`myAddFunc: ${x} + ${y} =  `, myAddFunc(x, y));
  15  
 16   //  1.2 书写完整函数类型 
 17  let myCompleteAddFunc: (baseValue: number, increment: number) =>  number
  18      =  function (x: number, y: number): number {
  19           return  x +  y;
  20       }
  21  console.log(`myCompleteAddFunc: ${x} + ${y} =  `, myCompleteAddFunc(x, y));
  22   /*  --------------------------------------------------------------------------  */ 
 23  
 24   /*  ------------------------------2.可选参数-----------------------------------  */ 
 25  function buildName(firstName:  string , lastName?:  string  ) {
  26       if   (lastName)
  27           return  firstName +  "   "  +  lastName;
  28       else 
 29           return   firstName;
  30   }
  31  let result1 = buildName( "  Bob  "  );
  32  let result2 = buildName( "  Bob  " ,  "  Adams  "  );
  33   /*  --------------------------------------------------------------------------  */ 
 34  
 35   /*  ------------------------------3.默认参数-----------------------------------  */ 
 36  function buildName2(firstName:  string , lastName =  "  Smith  "  ) {
  37       return  firstName +  "   "  +  lastName;
  38   }
  39  let result3 = buildName( "  Bob  "  );
  40  let result4 = buildName( "  Bob  "  , undefined);
  41  let result5 = buildName( "  Bob  " ,  "  Adams  "  );
  42   /*  --------------------------------------------------------------------------  */ 
 43  
 44   /*  ------------------------------4.剩余参数-----------------------------------  */ 
 45   function AddMany(...numbers: number[]) {
  46      let sum =  0  ;
  47       for  (let index =  0 ; index < numbers.length; index++ ) {
  48          sum +=  numbers[index];
  49       }
  50       return   sum;
  51   }
  52  let [w, z] = [ 3 ,  4  ];
  53  console.log(`AddMany ${x}+${y}+${w}+${z} =  `, AddMany(x, y, z, w));
  54   /*  --------------------------------------------------------------------------  */ 
 55  
 56   /*  ------------------------------5.箭头函数-----------------------------------  */ 
 57   //   注意:箭头函数能保存函数创建时的 this值,而不是调用时的值 
 58  let deck =  {
  59      suits: [ "  hearts  " ,  "  spades  " ,  "  clubs  " ,  "  diamonds  " ],    //  [红,黑,草,方] 
 60      cards: Array( 52 ),    //   不带大小王的哦 
 61       createCardPicker: function () {
  62           //   在使用箭头函数后,下面的这个this指代的就是deck这个对象了 
 63           return  () =>  {
  64              let pickedCard = Math.floor(Math.random() *  52  );
  65              let pickedSuit = Math.floor(pickedCard /  13  );
  66  
 67               return  { suit:  this .suits[pickedSuit], card: pickedCard %  13   };
  68           }
  69       }
  70   }
  71  let cardPicker =  deck.createCardPicker();
  72  let pickedCard =  cardPicker();
  73  console.log( "  你拿到的牌是:   "  + pickedCard.card +  "   of   "  +  pickedCard.suit);
  74   /*  --------------------------------------------------------------------------  */ 
 75  
 76   /*  ------------------------------6.函数重载----------------------------------  */ 
 77  let suits = [ "  hearts  " ,  "  spades  " ,  "  clubs  " ,  "  diamonds  "  ];
  78   //  重载的话先把可能遇到的参数类型先一一列举出,再用最后一个使用any参数的函数囊括各个情况,具体实现每种参数情况下的处理方式 
 79  function pickCard(x: { suit:  string  ; card: number; }[]): number;
  80  function pickCard(x: number): { suit:  string  ; card: number; };
  81   function pickCard(x: any): any {
  82       //   如果传入的是一个对象或者数组,也就是用户传进来的就是几张牌,这样的话我们就从中抽一张 
 83       if  ( typeof  x ==  "  object  "  ) {
  84          let pickedCard = Math.floor(Math.random() *  x.length);
  85           return   pickedCard;
  86       }
  87       //   传入的是一个数组的话,就根据这个数抽一张牌 
 88       else   if  ( typeof  x ==  "  number  "  ) {
  89          let pickedSuit = Math.floor(x /  13  );
  90           return  { suit: suits[pickedSuit], card: x %  13   };
  91       }
  92   }
  93  let myDeck = [{ suit:  "  diamonds  " , card:  2  }, { suit:  "  spades  " , card:  10  }, { suit:  "  hearts  " , card:  4   }];
  94  let pickedCard1 =  myDeck[pickCard(myDeck)];
  95  console.log( "  你拿到的牌是:   "  + pickedCard1.card +  "   of   "  +  pickedCard1.suit);
  96  
 97  let pickedCard2 = pickCard( 18  );
  98  console.log( "  你拿到的牌是:   "  + pickedCard2.card +  "   of   "  +  pickedCard2.suit);
  99   /*  --------------------------------------------------------------------------  */ 

TypeSrcipt 类

   1  console.log("------------------------------------------------" );
    2  console.log("TypeSrcipt 类" );
    3  
   4   /*  传统js中没有class的概念,从ES6引入  */ 
   5   /*  ---------------------------------1.类------------------------------------  */ 
   6   //  1.1 定义一个类 
   7   //  tips: 在ts中,类中变量和方法的默认访问修饰符是public 
   8   class Person {
    9       //  局部变量 
  10       protected readonly name: string;
   11       protected readonly age: number;
   12      private phone: string = "138555555555" ;
   13      private address: string = "221B Baker St" ;
   14  
  15       //  构造函数 
  16       constructor(name: string, age: number) {
   17           this .name =  name;
   18           this .age =  age;
   19       }
   20       /*   上面的简化写法:在一个地方定义并初始化一个成员
   21           constructor(readonly name: string,readonly age: number) {
   22           }
   23       */ 
  24  
  25       //  存取器(属性) 
  26       get contact(): string {
   27           return  `${ this .phone}—${ this  .address}`;
   28       }
   29       set contact(newVal: string) {
   30           if  (newVal && newVal.includes("—" )) {
   31              [ this .phone,  this .address] = newVal.split("—" );
   32           }
   33           else   {
   34              console.log("Incorrect format" );
   35           }
   36       }
   37       //  方法 
  38       greet() {
   39          console.log(`Hi, i am ${ this  .name}`);
   40       }
   41   }
   42   //  1.2 创建一个类的实体 
  43  let sherlock =  new  Person("sherlock", 24 );
   44  sherlock.greet();        //  Hi, i am sherlock 
  45   //  读属性 
  46  console.log(sherlock.contact);       //  138555555555—221B Baker St 
  47   //  写属性    
  48  sherlock.contact = "13966666666—211B Baker St"
  49   //  再读新属性 
  50  console.log(sherlock.contact);       //  13966666666—211B Baker St 
  51   /*  --------------------------------------------------------------------------  */ 
  52  
  53   /*  ---------------------------------2.继承------------------------------------  */ 
  54   //  2.1 继承类的关键字:extends 
  55   class Doctor extends Person {
   56       diagnose() {
   57           console.log(`diagnose illness...`)
   58       }
   59   }
   60  
  61   //  如果子类也有自己的构造函数,那么还必须要调用父类的构造函数,写法就是super() 
  62   class Teacher extends Person {
   63       private school: string;
   64       constructor(name: string, age: number, school: string) {
   65           super(name, age);
   66           this .school =  school;
   67       }
   68       teach() {
   69          console.log(`teach at ${ this  .school} ...`);
   70       }
   71   }
   72  
  73   //  2.2 创建子类 
  74  let Alice =  new  Doctor("Alice", 28 );
   75  Alice.greet();       //  Hi, i am Alice 
  76  Alice.diagnose();    //  diagnose illness... 
  77  
  78  let Howard: Teacher =  new  Teacher("Howard", 35, "Kw HighSchool" );
   79  Howard.greet();      //  Hi, i am Howard 
  80  Howard.teach();      //  teach at Kw HighSchool ... 
  81   /*  --------------------------------------------------------------------------  */ 
  82  
  83   /*  -------------------------------3.抽象类------------------------------------  */ 
  84   //  给其他类来继承的,不能创建一个抽象类的实例 
  85   abstract class Animal {
   86      abstract makeSound():  void ;      //  抽象类的抽象方法我们不需要实现,关键字:abstract 
  87  
  88      move():  void   {
   89          console.log('roaming the earch...' );
   90       }
   91   }
   92   //  定义抽象类的派生类 
  93   class Dog extends Animal {
   94      makeSound():  void   {
   95          console.log('wong wong wong...' );
   96       }
   97  
  98      eat():  void   {
   99          console.log('happiness...' )
  100       }
  101   }
  102  
 103  let xiaobai: Animal;     //   允许创建一个对抽象类型的引用 
 104  xiaobai =  new  Dog();     //   允许对一个抽象子类进行实例化和赋值 
 105  xiaobai.makeSound();     //   wong wong wong... 
 106   //  xiaobai.eat();        // Error :因为声明的是Animal类型,Dog类的方法无法调用到 

TypeSrcipt 接口

   1  console.log("------------------------------------------------" );
    2  console.log("TypeSrcipt 接口" );
    3   //  接口作用的简单总结:定义契约 
   4  
   5   /*  -------------------------------1.接口的作用----------------------------------  */ 
   6   //  TypeScript中接口与C#中有一点不一样,TypeScript中的接口是一个非常灵活的概念,除了可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。 
   7   interface LabelledValue {
    8       label: string;
    9   }
   10  
  11   //  用接口进行“约束”的对象,其字段不能多一个也不能少一个 
  12  let obj: LabelledValue =  {
   13      label: 'myObj' ,
   14       //  NO: 1002    //报错 
  15   }
   16  
  17   function   printLabel(labelledObj: LabelledValue) {
   18       console.log(labelledObj.label);
   19   }
   20  
  21  let myObj = { size: 10, label: "Size 10 Object"  };
   22   printLabel(myObj);
   23   /*  ---------------------------------------------------------------------------  */ 
  24  
  25   /*  -------------------------------2.可选参数------------------------------------  */ 
  26   interface SquareConfig {
   27      color?: string;      //  加上 ? 就表示参数是可选的了 
  28      width? : number;
   29   }
   30  
  31  let squareValue: SquareConfig =  {
   32      width: 10
  33       //  width2: 20    //但是新属性还是不行的 
  34   }
   35  
  36   function   createSquare(config: SquareConfig): { color: string; area: number } {
   37      let newSquare = { color: "white", area: 100  };
   38       if   (config.color) {
   39          newSquare.color =  config.color;
   40       }
   41       if   (config.width) {
   42          newSquare.area = config.width *  config.width;
   43       }
   44       return   newSquare;
   45   }
   46  
  47  let mySquare = createSquare({ color: "black"  });
   48   /*  ---------------------------------------------------------------------------  */ 
  49  
  50   /*  -------------------------------3.任意属性------------------------------------  */ 
  51   //  接口允许有一个任意的属性 
  52   //  需要注意的是:一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集 
  53   interface Dop {
   54       name: string;
   55      age? : number;
   56      [prop: string]: any;     //  我们定义的任意类型是any类型,name和age的类型都是any的子集,所以编译通过,当然这里也可以使用联合类型来定义“stirng | number” 
  57   }
   58  let tom: Dop =  {
   59      name: 'Tom' ,
   60      gender: 'male'
  61   };
   62  let jerry: Dop =  {
   63      name: 'Tom' ,
   64      age: 25 ,
   65      gender: 'male'
  66   };
   67   /*  ---------------------------------------------------------------------------  */ 
  68  
  69   /*  ----------------------------4.函数类型的接口---------------------------------  */ 
  70   /*   刚刚上面使用接口去约束了参数的形式,接口也可以约束函数的形式
   71   */ 
  72  
  73   interface SearchFunc {
   74      (source: string, subString: string):  boolean  ;
   75   }
   76  
  77   /*  
  78   ① 参数名称不是强制一样的,只要参数类型相同即可
   79   ② 实现接口的方法,如果不指定参数类型,TypeScript的类型系统会推断出参数类型
   80   */ 
  81   let mySearch: SearchFunc;
   82  mySearch =  function   (src, sub) {
   83      let result =  src.search(sub);
   84       return  result > -1 ;
   85   }
   86   /*  ---------------------------------------------------------------------------  */ 
  87  
  88   /*  ----------------------------5.可索引类型接口----------------------------------  */ 
  89   interface IArray {
   90       [index: number]: string
   91   }
   92   //  这种方式也可以来定义一个数组,但是单纯定义一个数组时我们不会这么定义,太复杂了 
  93   var  myArr: IArray = ["jack", "john", "jim" ];
   94  
  95   interface IObj {
   96       [index: string]: string
   97   }
   98  
  99   var  myObject: IObj = { name: "jack", email: "123@126.com"  };
  100   /*  ----------------------------------------------------------------------------  */ 
 101  
 102   /*  -------------------------------6.类类型接口----------------------------------  */ 
 103   //  定义一个接口来约束一个英雄该有的内涵,嘿嘿 
 104   interface IHero {
  105       position: heroType;
  106       level: number;
  107       heroName: string;
  108       phrase: string;
  109      attack():  void  ;
  110   }
  111   enum heroType {
  112       warrior,
  113       wizard,
  114       archer,
  115       tank,
  116       assassin
  117   }
  118   //  定义类型实现接口IHero,关键字“implements” 
 119   class Hero implements IHero {
  120       position: heroType;
  121       level: number;
  122       heroName: string;
  123       phrase: string;
  124       constructor(pos: heroType, lev: number, name: string, phrase: string) {
  125           this .position =  pos;
  126           this .level =  lev;
  127           this .heroName =  name;
  128           this .phrase =  phrase;
  129       }
  130      attack():  void   {
  131          console.log(`${ this .phrase}!!! `);
  132       }
  133   }
  134  let yasuo: Hero =  new  Hero(heroType.warrior, 1, "疾风剑豪", "ha sa ki" );
  135   yasuo.attack();
  136   /*  ---------------------------------------------------------------------------  */ 

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

  阅读:59次