TypeScript是微軟開發的一個JavaScript的超集,我的感受就是基於Js之上增長更多強類型約束與檢查機制,是一個嚴格模式模式下的嚴格Js(禁止套娃)。特別是對於熟悉後臺開發的同志,不少地方都會觸發共鳴(特別是C#開發者,畢竟TypeScript是微軟推出的,固然會有親兒子的影子)。可是在學習TypeScript以前呢,最好要有JavaScript和ES6知識的基礎,否則磕磕碰碰的學會打消積極性的。廢話少說,開始水博客,這裏記錄本人學習ts路上的一些筆記,本人主要是根據官方文檔和中文官網一篇篇看下來的,中途無心間撞見阮一峯大佬的教程以爲挺不錯的,推薦想快速入門的同志們參考。html
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);
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 /*--------------------------------------------------------------------------*/
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類的方法沒法調用到
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 /*---------------------------------------------------------------------------*/