因為工作需求,有需多缺乏的技能需要補齊,TypeScript 就是其中一項。 上班看不懂的時候邊查詢,空閒時間再來上課不足不懂的知識點,但還是得透過文章的整理來好好消化一下! 既然要開始介紹 TypeScript 就先來說說使用它的原因吧。
為什麼使用 TypeScript 
使程式碼更容易理解 (如函式需傳入的參數可以明確設定型別) 
減少程式碼撰寫的錯誤 
可以完全兼容JavaScript,此外能與 ES6 完美結合,並提供更多支援寫法。 
 
安裝介紹 
就是直接到官方網站查看,依需求安裝 
 
npm install -g typescript
型別介紹 從 JavaScript 型別分類開始
字串 string 
和ES6一樣,可以使用[字串樣板 Template Literals]1 2 3 let  firstName :string  = 'NaNa' let  message : string  = `Hello,${firstName} ` 
 
布林值 boolean  
 
布林值是最基礎的資料型別,在 TypeScript 中,使用 boolean 定義布林值型別: 
1 let  isDonw :boolean  = false  
 
注意:使用建構函式 Boolean 建立的物件不是布林值:
事實上 new Boolean() 返回的是一個 Boolean 物件1 2 3 4 let  createdByNewBoolean : boolean = new  Boolean (1 );
 
1 在 TypeScript 中,boolean 是 JavaScript 中的基本型別,而 Boolean 是 JavaScript 中的建構函式。 
 
 
 
數值 number 1 2 3 let  age :number  = 10 let  notANumber : number  = NaN ;let  infinityNumber : number  = Infinity ;
 
Null 和 Undefined 
與 void 的區別是,undefined 和 null 是所有型別的子型別
unfefined 可以賦值給number類型的變數 
陣列被赋值為 undefined 或 null 不会报错 
let num:number = undefined 
 
 
 
1 2 3 4 5 6 let  u : undefined  = undefined ;let  n : null  = null ;let  u : undefined ;let  num : number  = u;
 
void 
通常用在當函式沒有回傳值時。 
而 void 型別的變數不能賦值給 number 型別的變數:1 2 3 4 let  u : void ;let  num : number = u;
 
any  
在任意值上任何属性都是允許的
當有明確型別時,應避免使用 any  
因為 any 可以任意調用方法和屬性,很有可能出現錯誤(就喪失類型檢查的意義) 如果是 any 型別,則允許被賦值為任意型別 
 
 
 
1 2 let  myFavoriteNumber : any  = 'seven' ;myFavoriteNumber = 7 ; 
 
未宣告型別的變數 變數如果在宣告的時候,未指定其型別,那麼它會被識別為任意值型別:
1 2 3 4 5 let  something;something = 'seven' ; something = 7 ; something.setName ('Tom' ); 
 
陣列 Array 與 元組 Tuple 陣列 
在想宣告的型別後面加上[],宣告為某個型別的Array1 let  idList :number [] = [1 ,2 ,3 ]
 
使用陣列泛型,Array <元素型別>1 let  list :Array <number > = [1 ,2 ,3 ]
 
 
注意,當已經宣告這是個數字陣列
要 push 字串進去,會出現錯誤1 2 let  list :Array <number > = [1 ,2 ,3 ]list.push ("4" ) 
 
元組 Tuple  
剛剛的陣列將同一類型的數據放在一起,但是,想加入不同型別的數據怎麼辦? 
表示方式與陣列相似,將型別寫在[] 
有固定長度和元素型別的陣列1 2 3 4 let  user : [string , number ] = ['viking' , 20 ]user = ['molly' , 20 , true ] 
 
 
 
 
 
元組 
物件的型別——介面 (Interface) 
Interface 可以用來定義物件,還有由物件所延伸的型別(例如,陣列、函式) 
age?: number; 在該屬性後面加上 ? 表示為可選屬性 ,也就是在宣告新的物件時,可以彈性加入或不加入age (也不會報錯) 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 interface  Person  {  name : string ;   age : number ; } let  NaNa : Person  ={  name : 'NaNa' ,   age : 20  } interface  Person  {    name : string ;     age?: number ; } let  NaNa : Person  = {    name : 'NaNa'  } 
 
唯讀屬性 
readonly 是用在屬性上面 
希望物件中的一些欄位只能在建立的時候被賦值,那麼可以用 readonly 定義唯讀屬性 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 interface  Person  {  readonly  id : number ;   name : string ;   age?: number ; } let  Vic : Person  ={  id :1 ,     name : 'Vic' ,   age : 20  } Vic .id  = 9527 
 
函式型別 
函式可以作為參數、可以存入陣列,可以被另外一個函式返回、可以被賦值另外一個變數 
函式是由兩部分構成,一個是輸入(通過不同參數來實現),二為輸出(就是函數的返回結果)例子一  
設定參數型別、返回的型別 
若參數設定了 x、y兩個,也就只能放入兩個1 2 3 4 function  add (x: number , y: number  ): number  {  return  x + y } 
 
 
 
例子二 
1 2 3 4 5 6 7 8 function  add (x: number , y: number , z?: number  ): number  {  if  (typeof  z === 'number' ) {     return  x + y + z   } else  {     return  x + y   } } 
 
而在可選參數後面不可以再添加確定參數 
 
例外說明:引數預設值 
在 ES6 中,我們允許給函式的引數新增預設值,TypeScript 會將添加了預設值的引數識別為可選引數: 
 
1 2 3 4 5 function  buildName (firstName: string , lastName: string  = 'Cat'  ) {    return  firstName + ' '  + lastName; } let  tomcat = buildName ('Tom' , 'Cat' );let  tom = buildName ('Tom' ); 
 
此時就不受「可選引數必須接在必需引數後面」的限制了:
1 2 3 4 5 function  buildName (firstName: string  = 'Tom' , lastName: string  ) {    return  firstName + ' '  + lastName; } let  tomcat = buildName ('Tom' , 'Cat' );let  cat = buildName (undefined , 'Cat' );
 
例子三 
1 2 3 4 5 6 7 8 9 10 11 const  add = (x : number , y : number , z?: number ): number  =>  {  if  (typeof  z === 'number' ) {     return  x + y + z   } else  {     return  x + y   } } const  add2 : (x: number , y: number , z?:number  ) =>  number  = add
 
函式不只輸入、輸出有類型,本身也有類型 
將 add2 賦予 string 會出錯誤 
所以須聲明一模一樣的 const add2: (x: number, y: number, z?:number) => number = add 
 
例子四 
使用 interface (單純定義函式的 Interface) 
 
1 2 3 4 5 6 7 8 const  sum  = (x: number , y: number  ) => {  return  x + y } interface  ISum  {  (x : number , y : number ): number  } const  sum2 : ISum  = sum
 
1 2 3 4 5 6 7 8 interface  SearchFunc  {    (source : string , subString : string ): boolean ; } let  mySearch : SearchFunc ;mySearch = function (source: string , subString: string  ) {     return  source.search (subString) !== -1 ; } 
 
 
型別推論(Type Inference)\ 聯合型別(Union Types) \ 型別斷言(Type Assertion) 型別推論(Type Inference) 
可以推論出我們賦值過程中,這個變數應該是什麼類型的 
TS 會在沒有明確指定型別的時候,推測出型別 
 
聯合型別(Union Types) 
用分隔符號 
當 TypeScript 不确定一个聯合型別的變數到底是哪個型別的时候,我们只能使用此聯合型別的所有型別裡共有的屬性或方法 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 let  numberOrString : number  | string  numberOrString.length    numberOrString.toString ()  function  getLength (something: string  | number  ): number  {    return  something.length ; } 
 
聯合型別的變數在被賦值的時候,會根據型別推論的規則推斷出一個型別: 
 
1 2 3 4 5 6 let  numberOrString : string  | number ;numberOrString = 'seven' ; console .log (numberOrString.length ); numberOrString = 7 ; console .log (numberOrString.length ); 
 
上例中,第二行的 numberOrString 被推斷成了 string,存取它的 length 屬性不會報錯。 而第四行的 numberOrString 被推斷成了 number,存取它的 length 屬性時就報錯了。
type guard  
當遇到聯合類型,可以使用條件語句,自動幫你縮小型別範圍 
 
1 2 3 4 5 6 7 8 function  getLength2 (input: string | number ): number {  if  (typeof  input === 'string' ) {     return  input.length    } else  {     return  input.toString ().length    } } 
 
型別斷言(Type Assertion) 
開發者比 TS 更了解編寫的程式碼。因此,TS 允許開發者覆蓋它的推論,這樣的機制稱為「型別斷言」。 
 
1 2 3 4 5 6 7 8 9 10 function  getLength (input: string  | number  ): number  {  const  str = input as  string    if  (str.length ) {     return  str.length    } else  {     const  number  = input as  number      return  number .toString ().length    } } 
 
型別斷言不是型別轉換,斷言成一個聯合型別中不存在的型別是不允許的: 
 
1 2 3 4 5 6 7 function  toBoolean (something: string  | number  ): boolean  {    return  <boolean >something; } 
 
基礎型別先介紹到這裡,下篇將介紹一些進階用法~
資料來源:
線上課程:實戰 Vue3.0(正式版) + TS  
TypeScript 新手指南