如何實作下列這個函數?
function padLeft(padding: number | string, input: string) {
}

編譯錯誤的原因:
TypeScript 警告我們将數字添加到數字 | string 可能不會給我們想要的東西,這是對的。 換句話說,我們沒有先明确檢查 padding 是否是數字,也沒有處理它是字元串的情況。
正确的做法:
function padLeft(padding: number | string, input: string) {
if (typeof padding === "number") {
return new Array(padding + 1).join(" ") + input;
}
return padding + input;
}
如果這看起來像是無趣的 JavaScript 代碼,那就是重點。除了我們放置的注釋之外,這個 TypeScript 代碼看起來像 JavaScript。這個想法是 TypeScript 的類型系統旨在使編寫典型的 JavaScript 代碼盡可能容易。
雖然它看起來可能不多,但實際上這裡有很多事情要做。就像 TypeScript 如何使用靜态類型分析運作時值一樣,它将類型分析覆寫在 JavaScript 的運作時控制流結構上,例如 if/else、條件三元組、循環、真實性檢查等,這些都會影響這些類型。
在我們的 if 檢查中,TypeScript 看到 typeof padding === “number” 并将其了解為一種稱為類型保護(Type guard)的特殊代碼形式。 TypeScript 遵循可能的執行路徑,我們的程式可以采用這些路徑來分析給定位置的值的最具體可能類型。它着眼于這些特殊檢查(稱為類型保護)和指派,并将類型細化為比聲明的類型更具體的類型的過程稱為縮小。在許多編輯器中,我們可以觀察這些類型的變化。
比如,在第二個 return 語句裡,因為前一個 IF 語句的條件沒有滿足,是以代碼執行到這裡時,padding 的類型一定隻能是 string 了。
看下面這段代碼:
function printAll(strs: string | string[] | null) {
if (typeof strs === "object") {
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === "string") {
console.log(strs);
} else {
// do nothing
}
}
編譯錯誤:Object is possibly ‘null’.
在 printAll 函數中,我們嘗試檢查 strs 是否為對象以檢視它是否為數組類型(現在可能是強調數組是 JavaScript 中的對象類型的好時機)。 但事實證明,在 JavaScript 中,typeof null 實際上是“object”! 這是曆史上的不幸事故之一。
有足夠經驗的使用者可能不會感到驚訝,但并不是每個人都在 JavaScript 中遇到過這種情況; 幸運的是,TypeScript 讓我們知道 strs 隻縮小到 string[] | null 而不僅僅是 string[]。
這可能是我們所謂的“真實性”檢查的一個很好的過渡。
雙感歎号是 Boolean 函數調用的簡寫形式。
是以上面的代碼可以修改成:
使用 in 關鍵字進行的 narrowing
function printAll(strs: string | string[] | null) {
if (strs && typeof strs === "object") {
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === "string") {
console.log(strs);
} else {
// do nothing
}
}
Javascript 有一個運算符來确定對象是否具有帶名稱的屬性:in 運算符。 TypeScript 将這一點作為縮小潛在類型的一種方式。
例如,使用代碼:x 中的“值”。 其中“value”是字元串文字,x 是聯合類型。 “true”分支縮小了具有可選或必需屬性值的 x 類型,“false”分支縮小到具有可選或缺失屬性值的類型。
例子:
type Fish = { swim: () => void };
type Bird = { fly: () => void };
function move(animal: Fish | Bird) {
if ("swim" in animal) {
return animal.swim();
}
return animal.fly();
}
1
2
3
4
5
6
7
8
9
10
/118191351