TypeScript 筆記:void 與 any


Posted by SimonAllen on 2021-08-10

TypeScript 是 JavaScript 的超集合,最終還是編譯成 JavaScript,除了原本 JavaScript 的型別系統,TypeScript 還新增了一些特殊型別,例如:void、any、never 與 unknown。
此篇先以 void 與 any 介紹為主:

void

void 表示沒有 return 返回值的函數回傳值(空值)型別。

在撰寫 JavaScript 函式、方法時,函式不一定要 return 返回值出來,它不一定是有輸入就有輸出的 pure function。例如 JavaScript 我們可以這樣寫:

let a = 1;
function add(){
    a = a + 1
    console.log(a)
}
add()

先不討論 add 這個函式乾不乾淨,至少上面程式碼是符合 JavaScript 規範的。而在 TypeScript 的設計裡,它預期每個函式、方法會有回傳 return 的機制在,但是我們在 add 函式內直接修改外部變數,函式並沒有 return 任何值到外部。

當函式沒有任何程式段落 return 值到外部時,就(會)要用 void 來規範,表示這個函式的回傳值空。所以上面的函式,若不使用型別推斷而是自己加上註記,在 TypeScript 就可以寫成這樣:

function add(): void {
  a = a + 1;
  console.log(a);
}

另外,使用 void 限制型別再賦值 null 或 undefined 沒有意義,雖然 null 和 undefined 是所有型別的子型別,除非改 config 否則這麼寫不會報錯

let nothing: void = null;

但這樣寫完全沒意義,不如直接限制 null 或 undefined,void 還是用在函數的回傳型別為主。

其他的強型別程式語言也有 void 的設計,只是 JavaScript 沒有,為了避免和其他前端工程師討論中文空值時不知道是指 void 還是 null,建議用英文原文術語 void 討論會好一點。

any

any 又稱為 TypeScript 的通用型別或任意型別,是所有型別的聯集,使用 any 會允許 TypeScript 在之後仍可以賦值為任意型別。

let a: any = 100
a = "100"
a = []

不過這樣寫型別規範,使用 TypeScript 就沒意義了。

此外 any 比較常出現在型別推論之時。當我們進行延遲性指派(先宣告變數再賦值),TypeScript 會替預先宣告好的變數定義為 any 型別。

let a;
a = 100;

要注意和原本 JavaScript 的差異:延遲性指派預先宣告變數時,JavaScript 新變數預設型別為 undefined,而 TypeScript 除非到 tsconfig.json 中設定 noImplicitAny,否則預設新變數型別為 any。

還有要注意的是, any 不只允許被賦值為任意型別,在 any 值上訪問任何屬性或呼叫方法都是允許的,例如這樣註記 : number 會提示:

let year: number = 2021;
console.log(year.a)

如果在 VS Code 這樣寫 TypeScript 就會提示錯誤

仍然編譯的話就會報錯,這很合理,year 變數沒有 a 屬性,數值原形練也沒有 a 存在,編譯時就報錯合理。然而,若我們將 : number 改成 : any,TypeScript 會允許編譯成功。

let year: any = 2021;
console.log(year.a)

之後執行 JavaScript 時,因為沒有 a 的存在,所以 JavaScript log 就會印出 undefined,但是這樣寫沒有意義..。

撇開型別推論,開發者主動註記 any 更像是 TypeScript 給予開發者的一種彈性,主動註記或斷言 any 不是不能用(例如接手前人 code 改成 TypeScript 時),但用前先想想,因為強迫開發者在撰寫時先限制型別正是 TypeScript 的用意之一,若版本允許,使用 unknown 會比 any 更好一點,若之後有時間會再分享 unknown 與 never 的介紹。

              

參考

TypeScript 新手指南
TypeScript: Typed JavaScript at Any Scale.
kobo 電子書:讓TypeScript成爲你前端開發的ACE!
Typescript 初心者手札


#TypeScript









Related Posts

命題邏輯(Propositional Logic)

命題邏輯(Propositional Logic)

原始資料類型(Primitive Data Type)& 參考資料類型(Reference Data Type)

原始資料類型(Primitive Data Type)& 參考資料類型(Reference Data Type)

輸入資料 是否為自然數的 判斷演算法

輸入資料 是否為自然數的 判斷演算法


Comments