初探TypeScript

Share This Post

TypeScript 到底是什麼?

由 Microsoft 主打,擁有型別系統(Type System)與介面(Interface)設計的語言,

TypeScript 與 JavaScript 的相容性

TypeScript 是 ECMAScript 2015 (ECMAScript 6 或 ES6) 的 strict 超集。 這表示所有的 JavaScript 程式碼也是 TypeScript 程式碼,而 TypeScript 程式可順利地取用 JavaScript。

瀏覽器只能了解 JavaScript。 為了讓您的應用程式得以運作,使用 TypeScript 撰寫時,請編譯程式碼,並將其轉換為 JavaScript。

圖片來源

TypeScript 本身的優點

  1. 加強「Type」部分的JavaScript
  2. 開發完成後還是需要編譯成JavaScript
  3. 適用於開發前後端

建立環境

新增

npm install -g typescript

TS 初始化設置文件並會產生tsconfig.json 檔案

tsc --init

預設的config檔案

{
    "compilerOptions": {
        "target": "es2016",  //指定編譯生成的JS版本
        "module": "commonjs", //指定生成哪種模組
        "strict": true,  //採用嚴格模式  
        "esModuleInterop": true,  //兼容模組導入的方式
    }
}

新增我們config檔案設定,其他詳細的config設定

"outDir": "./dist", //完成編譯後生成 js 文件的路徑                           
"rootDir": "./src",   //代表 ts 文件的入口路徑
"strictNullChecks": true // 將 null 與 undefined 視為不同的型別
"strictPropertyInitialization":false //啟用所有嚴格類型檢查模式


圖片來源
(在預設狀況下(strictNullCheck 為 false),值為 undefined 或 null會被推論為 any型別,因為這時候 undefined 和 null 可以是任何資料型別的值)


建立一個檔案index.ts

const message='Hi';functionsay(something:string):void{console.log(something);}say(message);

執行編譯
TypeScript 編譯器就會幫我們自動掃描所有 .ts 結尾的檔案並且產出 JS 檔案。
(在未提供其他參數的情況下執行,會編譯目前資料夾中所有的.ts檔案,額外延伸 tsc 命令列介面文件

tsc

好用指令推推
每當TS檔案有改變時,自動編譯JS檔案

tsc --watch

型別推論(Type Inference)

使用「類型提示」來識別變數或參數的資料類型。
→ 可透過靜態類型檢查,在開發初期就找出程式碼問題。

let a =123;// TS 編譯器便會自動推論出資料型別為number

結論:没有明確指定型別的情況下,由 TS 自動判斷型別

型別斷言(Type Assertion)

編譯器接受開發者手動寫下型別,並且不會再送出警告錯誤。
語法:

  1. <型別>值 (angle-bracket <>)寫法let code:any=123;let employeeCode =<number> code;
  2. 值as 型別 (as keyword)寫法
let code:any=123;let employeeCode = code asnumber;

兩者寫法效果相同,但React專案使用JSX語法時只能用第二種。

結論:手動指定資料型別,可以覆蓋掉 TS 自動推論的資料型別

型別註解(Type Annotation)

使用手動註解的方式,明確宣告資料型別,告訴編譯器必須符合註解的類型。
語法:在變數、參數或屬性後面加上冒號:型別

//變數的型別註解const age:number=32//函式參數的型別註解functiondisplay(name:string){console.log(name);}//函式參數/回傳值的型別註解functiondisplay(a:number,b:number):number{return a + b
}

結論:明確指定資料型別。

型別註解 v.s 型別斷言

  1. 大部分情況下會使用型別註解 ; 型別斷言使用情境較少。
  2. 型別註解告訴編譯器這個資料必須永遠都是這個型別 ; 而型別斷言則主要用在覆蓋 TS 編譯器自動進行的型別推斷和型別相容性規則(Type Compatibility),告訴編譯器你知道這個值要符合斷言的型別,從而避免了上面範例中型別不兼容的錯誤產生。關於兼容性的討論在stackoverflow看到不錯的討論。
  3. 型別註解大部分使用在初始化階段,像是宣告變數、函式參數或回傳值型別等 ; 而型別斷言可能用在接收外部參數,中間過程需要明確指定資料型別的時候

資料型態

基本型別(Basic Types)

Type型別分類筆記
stringprimitive定義字串型別。
numberprimitive定義數值型別。
booleanprimitive定義布林值型別。
nullprimitive定義空值型別, 亦可賦值給所有型別(嚴謹模式則無法),something is currently unavailable(當你使用在宣告了變數,但又不想讓它是未定義的狀態)。
undefinedprimitive定義 undefined 型別,亦可賦值給所有型別(嚴謹模式則無法), something hasn’t been initialized(變數沒有被宣告,或者是已經宣告了,但是沒有賦值)
// -----------------基本類型-----------------let name1:string='bob'let name2:string="bob"// 支援 10 進制和 16 進制,也支援 ES6 的 2 進制和 8 進制的最新寫法let decLiteral:number=6;let hexLiteral:number=0xf00d;// ES6 中的 2 進制表示法let binaryLiteral:number=0b1010;// ES6 中的 8 進制表示法let octalLiteral:number=0o744;let notANumber:number=NaN;let infinityNumber:number=Infinity;let boo:boolean=true;let name:any;
name =undefined// OK 
name =null// OKlet age:undefined; 
age =undefined// OK
age =null// Error 
age =123// Error let spot:null; 
spot =null// OK
spot =undefined// Error
spot =123// Error

JSON value 不支援 undefined

TypeScript 才有的型別 : any、unknown、void、 never、 union types(聯合型別) 、intersection types(交集型別)、 literal types(字面值型別)、 tuple(元組)、 enums(列舉)。

Type型別分類筆記
objectobject定義物件型別。
arraysobject可使用「型別 + 方括號」或陣列泛型來表示陣列。
functionobject一個函式有輸入和輸出,可以針對參數(輸入)及返回值(輸出)進行型別規範。
// 陣列let arr:string[]=['a','b'];let arr:Array<string>=['a','b'];let arr2:string[][]=[['aa','bb',1]]let arr3:string[][]=[['aa','bb'],[1]]let combine =[1,'hi','hello',2,'world'];// 針對混合型態的陣列推論結果為 (string | number)[],TS會當作聯合型別(union)來處理
// ----------------- object -----------------typeCard={
    name:string;
    desc:string;}interfaceCard2{
    name:string;
    desc:string;}const obj :Card={
    name:'bbb',
    desc:"---"};
// ----------------- object -----------------typeCard={
    name:string;
    desc:string;}interfaceCard2{
    name:string;
    desc:string;}interfaceCard2{
    age?:number;// 代表可以是number或undefined}const obj :Card2={
    name:'bbb',
    desc:"---"};
//----------------- 泛型 -----------------functionp<T>(data:T){console.log('data',data)}p<number>(9000);p<string>('wewe');p<boolean>(false);
//---------Function--------------//函式宣告式functionadd(x:number, y:number):number{return x + y;}//  函式表達式(匿名函式)letadd=function(x:number, y:number){return x + y;};
Type型別分類筆記
anyTS表示允許賦值為任意型別。
unknownTSunknown 和 any 一樣可以接受任何型別賦值,但 any 可以賦值給任何型別,unknown 只能賦值給 any 和自己。
voidTS表示沒有任何返回值的函式。
neverTS來表示不應該存在的狀態的型別,一般用於錯誤處理函式。
union typesTS聯合型別(union type) 使用|表示其定義的值可以為多種型別。
intersection typesTS交集型別(intersection type) 使用 & 表示其定義的值都必須符合多種型別。
literal typesTS某些特殊的”值”可以當作”型別”來使用。
tupleTStuple 就是合併了不同型別的物件。
enumTS列舉(enum)型別可以用來管理多個同系列的常數,作為狀態判斷使用。
typeA=number|string;let z :A;//變數Z屬於A類型,可接受number與string
z='wewewewew';
z=12121212;
z=true//物陣列的元素沒有你要的型別,可以用 union 聯合型別進行型別註記//不限定數量只要元素符合型別let foo:(string|number)[]=['hello','ya','yeah'];//或let foo:Array<string|number>=['hello','ya','yeah'];
// 元組,元素個數必須固定,各個元素格式也必須完全吻合let tuple:[number,String,boolean]=[1,'a',true];let tuple2:[String,String]=['a','a'];// -----------------Enum 枚舉-----------------// 以座位感測來舉例enum SeatStatus{ERROR=-1,USING=0,AVAILABLE=1,IDLE_TOO_LONG=2,}const staus=SeatStatus.ERROR;
// -----------------交集-----------------typeInfo1={
    name:string,
    age:number}typeInfo2={
    isGirl :boolean,
    nickname:string}typeIntersecInfo= Info1 & Info2

let person5 : IntersecInfo ={
    name :'Una',
    age:18,
    isGirl :true,
    nickname:'Nana'}

指定物件的類型

type vs interface:interface是可以擴充的但type不行

物件導向

//----------------- class -----------------// private// public// protectedclassLive{public roomName:string;private id :string;protected name:string;constructor(roomName1:string,id1:string,name1:string){console.log('直播中...')this.roomName=roomName1;this.id=id1;this.name=name1;}}const live=newLive('1賀','011111','12121');console.log(live);

參考資料:https://docs.microsoft.com/zh-tw/learn/modules/typescript-get-started/2-typescript-overview

https://ithelp.ithome.com.tw/articles/10217384
https://ithelp.ithome.com.tw/articles/10220016

訂閱研究文章

Get updates and learn from the best

More To Explore

Scroll to Top

hurry up !

軟體工程師培訓

限時免費報名中

藉由與「真實世界軟體專案」相同的技術、工具與開發流程,化簡成與商業機密無關、門檻較低更容易上手的「模擬專案」,讓你有機會在職場前輩的陪伴下,完成真槍實彈的練習,動手解決真實的問題,快速累積個人的經驗與作品,而不只是「學習技術」而已。