iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0

接續昨天的文章,我們刻意斷言斷錯型別,TypeScript説「你斷言斷錯型別了,如果你是故意的,要解決這個error的話,要先斷言成unknown唷」。我們今天來講講unknown到底是什麼?還有一些比較特殊的型別。

unknown

顧名思義就是未知(廢話),它的性質跟any有些類似,可以代表任何值,但又有所不同,我們來看例子:

function sayHi1(msg: any) {
    console.log(msg.toUpperCase())
    //正常運作不噴錯
}

function sayHi2(msg: unknown) {
    console.log(msg.toUpperCase())
    //Object is of type 'unknown'.
}

簡單來說,對一個變數/參數斷言他是any,我們可以對他取用任何方法/屬性,都不會報錯、可以正常編譯,哪怕它在runtime時真的是錯的。但unknown就不同了,因為對TypeScript來講,他是未知的,所以對他呼叫任何"可能"的方法,都會提前報錯,免得你在程式碼上線後,發生未知的錯誤。

unknownany到底要怎麼選擇,簡單來說,any比較隨性,TypeScript不會對任何設為any的值進行檢查,所以,就跟寫原生JS一樣,失去了使用TypeScript的優點。有些時候,我們可能會先宣告一個,還不確定型別的變數,這時就很適合給他unknown而非any,如此一來,我們在還沒進一步對這個變數進行型別斷言前,對該變數進行任何的操作都會報錯,可以讓我們很快的在編譯前發現錯誤。

而剛剛有提到any相對比較隨性,我們來看下面例子:

function casual(s){
    console.log(s.toFixed(2))
}

在這個情況下,我們的參數s,在沒有設定任何型別時,會被TypeScript推測為是any,因此對他進行任何方法都不會報錯,但我們引入TypeScript就是希望讓我們的code更加安全、更好維護,因此這行為不是我們樂見的。在未來會提到的TypeScript設定檔(config)中,其中有一項flag叫做noImplicitAny,開啟後,當我們遇到上述這種沒設定型別的情況,就會直接噴錯,避免我們"忘了"加上型別。

noImplicitAny!!!

never

never滿有趣的,就連官方對他的說明都很有限,通常使用於對函式回傳值型別宣告

function fail(msg: string): never {
  throw new Error(msg);
}

通常是用於1.函式拋出了例外 2.程式在執行過程中被中止了。
拋出例外還算好理解,但第二點...來看一下例子:

function fn(x: string | number) {
  if (typeof x === "string") {
    // do something
  } else if (typeof x === "number") {
    // do something else
  } else {
    x; // has type 'never'!
  }
}

上面是官方文件提供的範例,雖然有點雞肋,但我們的確能知道最後一個elseblock是絕對到不了的,所以那邊的x他是一個完全不可能被回傳/執行的值,它很明顯的是never("絕不"會被回傳/執行)。

void

既然剛剛有提到never,那就順便提到類似的void吧,這個的使用率絕對比never來得多,void代表的是「函式沒有回傳任何值」,注意,不是沒有return喔,是沒有回傳任何值。

function hello(){
    return;
}

void!

//TypeScript也會覺得這是void,因為我們完全沒有回傳值
function hello(){
    console.log("hello~~")
}

這兩個情境都是將型別設定於"回傳值"。那,我們可不可以為將變數設定成void呢?呃,是...是可以啦,但沒什麼意義。

let nothing: void = undefined;
let number: void = 1;
//Type 'number' is not assignable to type 'void'.

只有nullundefined可以指派void型別,但我還沒想到合宜的使用情境lol。

小結

以上是我在初步接觸TypeScript時,所看到比較特別的型別,畢竟就算看得懂它字面上的意義,我們還是得進到官方文件,去了解它到底該怎麼使用、要解決原生JavaScript的什麼問題。在這邊簡單介紹給大家,希望大家能分享一下你們實際使用到這些型別的情境為何。


上一篇
型別介紹part3 - 型別斷言
下一篇
第八天!Type Alias & Interface 型別別名與介面
系列文
你也對開始使用typescript感到無力嗎?我也是 - 30天初探typescript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言