首頁  >  文章  >  web前端  >  TypeScript 嚴格類型 - 部分完整靜態類型

TypeScript 嚴格類型 - 部分完整靜態類型

王林
王林原創
2024-08-01 01:51:22820瀏覽

TypeScript strictly typed - Part full static types

在本系列文章的前一部分中,我們討論了安全可空性。

現在我們將解釋並解決 TypeScript 預設行為的第三個問題,也是最後一個問題:動態類型的剩餘部分

我們將涵蓋:

  • 動態類型的遺跡
  • 實際平等檢查
  • 條件中沒有隱式轉換
  • 條件簡寫符號
  • 字串和數字不能混合

動態類型的殘餘

TypeScript 應該是一個“靜態類型檢查器”,與 JavaScript 不同,JavaScript 中的類型是深度動態的。

但在本系列文章的前一部分中,我們也解釋了 TypeScript 是作為 JavaScript 的超集建構的。

所以問題是:JavaScript 動態型別系統的某些部分仍保留在 TypeScript 中。因此,我們將解釋如何抑制這些剩餘行為以實現完全靜態類型

實際平等檢查

  • ESLint:eqeqeq
  • 生物群落:可疑.noDoubleEquals(推薦)

這個問題最好的例子就是相等性檢查。在 JavaScript 中,== 不完全是相等檢查,而是等價檢查:

1 == "1"; // true

儘管類型不同,但有些轉換規則會起作用,因此 JavaScript 能夠比較值。它可能會導致很多錯誤,因為規則細節很難記住,有時很奇怪,並且在所有動態語言(例如 PHP)中並不完全相同。

這些等價性檢查僅在 JavaScript 等動態類型語言中才有意義。從我們決定使用 TypeScript 的那一刻起,只應該使用實際的相等檢查(類型和值)。

1 === "1"; // false

eqeqeq lint 規則強制執行它。

來自 Java、C# 或 Rust 等語言的人應該特別小心這個問題,因為 JavaScript 或 TypeScript 中的 == 與這些語言中的含義不同。在 JavaScript 和 TypeScript 中,需要第三個 = 才能實現相同的行為。

條件中沒有隱式轉換

  • ESLint:@typescript-eslint/strict-boolean-expressions
  • 生物群系:缺少規則

認為現在情況安全嗎?不幸的是不是,因為轉換可以是隱式的:

let tax: number | undefined = 0;

if (tax) {
  console.log("Process payment");
}
if (!tax) {
  throw new Error();
}

上面的例子相當於:

let tax: number | undefined = 0;

if (tax == true) {
  console.log("Process payment");
}
if (tax == false) {
  throw new Error();
}

如您所見,存在隱式 ==,因此仍然會發生轉換:0 不等於 true,它相當於 false。因此,儘管稅費是有效值,它也會出錯。

嚴格布林表達式 lint 規則不允許此類隱式條件,並強制執行實際檢查:

let tax: number | undefined = 0;

if (tax !== undefined) {
  console.log("Process payment");
}
if (tax === undefined) {
  throw new Error();
}

對於習慣了 JavaScript 快速條件的人來說,這可能是最繁瑣的規則之一,但從長遠來看,這只是在 Java、C# 或 Rust 等其他語言中執行操作的正常方法。

如組態部分所示,停用allowNumber 和allowString 子選項對於避免所有錯誤非常重要。

唯一允許的例外是物件和陣列:這些情況是安全的,因為與字串和數字相反,它們沒有假值。所以下面的還是可以的:

let movie: Movie | undefined;
if (movie) {}
if (!movie) {}

注意:switch 語句已經安全,因為它們在內部使用 ===。

條件簡寫

  • ESLint:@typescript-eslint/prefer-nullish-coalescing(在風格類型檢查中)
  • 生物群系:缺少規則

嚴格布林表達式 lint 規則注意條件檢查是型別安全的,但除了 if 之外還有其他條件語法:

const movieRating = userRating || 5;

// Which is a shorter version of:
const movieRating = userRating == true ? userRating : 5;

如果使用者評分為 0,則 0 相當於 false,因此評分將為 5 而不是 0。

使用現代 JavaScript 可以避免這種情況:

const movieRating = userRating ?? 5;

// Which is a shorter version of:
const movieRating = userRating !== undefined && userRating !== null
  ? userRating
  : 5;

它可以透過prefer-nullish-coalescing lint規則強制執行。

請注意? ?不應在任何地方使用: ||在使用布林值時仍然相關。

字串和數字不能混合

  • ESLint:
    • 首選模板
    • @typescript-eslint/restrict-plus-operands(在建議類型檢查中)
    • @typescript-eslint/restrict-template-expressions(在建議類型檢查中)
  • 生物群落:
    • style.useTemplate(建議)
    • 缺少其他規則

在 JavaScript 中,+ 運算子既可用於數字的數學加法,也可用於字串連接。它會導致錯誤。

"There is " + 3 + 1 + "Matrix movies"; // 31
"There is " + (3 + 1) + "Matrix movies"; // 4

+ 運算子應該保留用於數學加法。或者至少,它應該僅用於相同類型的數據,這是限制加操作數 lint 規則強制執行的。

Template strings from modern JavaScript should be used for string concatenation, which the prefer-template lint rule enforces:

const movie = `Everything everywhere all at once`;
`${movie} is the best movie!`;

Conversely, only strings should be used in template strings, which the restrict-template-expressions lint rule enforces.

If mixing types is what is actually wanted, conversions should be explicit:

const total = 3;
`There is ${total.toFixed()} Matrix movies`;

Note that template strings can be nested:

const total = 3;
`There is ${total.toFixed()} Matrix movie${total > 1 ? "s" : ""}`;

Conclusion

This is the end of this posts series. You can follow my account (button on top right of this page) to know when other posts about TypeScript or other topics like Angular are published.

You want to contact me? Instructions are available in the summary.

以上是TypeScript 嚴格類型 - 部分完整靜態類型的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:什麼是 Node.js下一篇:什麼是 Node.js