TypeScript 3.7稳定版发布
TypeScript 3.7 發布了,此版本帶來了許多新特性。
Optional Chaining 首先一大亮點是 Optional Chaining,這是社區呼喚特別強烈的一個 ECMAScript 特性。最初它是 TypeScript 的 issue 跟蹤器上第 16 個 issue,于 5 年前提交,要知道目前總共有多達 23000 個 issue。 當時 TC39 還沒有正式提案,這些年來開發者一直要求實現該特性,但是為了不與 ECMAScript 建議沖突,遲遲沒有實現,相反 TS 開發團隊一直在幫助推動該提案實現標準化,并最終推及所有 JavaScript 與 TypeScript 開發者。 Optional Chaining 特性主要用于保護出現在屬性路徑中 null 和 undefined 值,像 C# 等語言中已經有用于訪問屬性鏈的語法糖,可以在對象層次結構中的任何地方處理遇到的 null 和 undefined 情況,使它可以正常執行,而不會拋出錯誤。具體來講,在向樹狀結構深處進行屬性值訪問時,通常需要檢查中間節點是否存在:
var street = user.address && user.address.street;
許多 API 返回一個對象或 null/undefined,并且可能只想在結果不為 null 時從結果中提取屬性:
var fooInput = myForm.querySelector('input[name=foo]')
var fooValue = fooInput ? fooInput.value : undefined
Optional Chaining 運算符允許開發人員直接用簡單的方式處理這種情況,而不用進行重復性操作,或者使用臨時變量分配中間結果:
var street = user.address?.street
var fooValue = myForm.querySelector('input[name=foo]')?.value
因為是保護訪問屬性鏈時的 null 與 undefined,所以 Optional Chaining 運算符也叫做“安全導航運算符”,TC39 標準中給出的該運算符是“?.”,它的語法可以適用于三種場景:
obj?.prop // 自判斷靜態屬性訪問
obj?.[expr] // 自判斷動態訪問
func?.(...args) // 自判斷函數或方法調用
考慮以下代碼:
let x = (foo !== null && foo !== undefined) ?
foo :
bar();
如果 foo 不為空并且不等于 undefined,則執行 bar()。它現在可以等效于:
let x = foo ?? bar();
斷言如果發生意外情況,則有一組特定函數會拋出錯誤,這被稱為斷言。例如 Node.js 有一個專用的 assert 函數:
assert(someValue === 42);
如果 someValue 不等于 42,則 assert 將拋出 AssertionError。JavaScript 中的斷言通常用于防止傳入不正確的類型,例如:
function multiply(x, y) {
assert(typeof x === "number");
assert(typeof y === "number");
return x * y;
}
不過在 TypeScript 中,會有一些類型問題:
function yell(str) {
assert(typeof str === "string");
return str.toUppercase();
// Oops! We misspelled 'toUpperCase'.
// Would be great if TypeScript still caught this!
}
替代方法是改寫代碼,以便語言可以對其進行分析,但這不太方便:
function yell(str) {
if (typeof str !== "string") {
throw new TypeError("str should have been a string.")
}
// Error caught!
return str.toUppercase();
}
第一種斷言簽名對 Node.js assert 的執行方式進行建模,它確保在包含范圍的其余部分中,無論檢查什么條件都必須為真。
function assert(condition: any, msg?: string): asserts condition {
if (!condition) {
throw new AssertionError(msg)
}
}
以前邊的 yell 為例,確實可以捕獲到類型錯誤:
function yell(str) {
assert(typeof str === "string");
return str.toUppercase();
// ~~~~~~~~~~~
// error: Property 'toUppercase' does not exist on type 'string'.
// Did you mean 'toUpperCase'?
}
function assert(condition: any, msg?: string): asserts condition {
if (!condition) {
throw new AssertionError(msg)
}
}
另一種斷言簽名不檢查條件,而是告訴 TypeScript 特定的變量或屬性具有不同的類型。
function assertIsString(val: any): asserts val is string {
if (typeof val !== "string") {
throw new AssertionError("Not a string!");
}
}
這里的 assert val is string,確保在對 assertIsString 進行任何調用之后,傳入的任何變量都將是字符串。
function yell(str: any) {
assertIsString(str);
// Now TypeScript knows that 'str' is a 'string'.
return str.toUppercase();
// ~~~~~~~~~~~
// error: Property 'toUppercase' does not exist on type 'string'.
// Did you mean 'toUpperCase'?
}
這些斷言簽名與編寫類型謂詞簽名非常相似:
function isString(val: any): val is string {
return typeof val === "string";
}
function yell(str: any) {
if (isString(str)) {
return str.toUppercase();
}
throw "Oops!";
}
類似類型謂詞簽名,這些斷言簽名也具有很強的表現力,可以用這些表達一些相當復雜的邏輯:
function assertIsDefined<T>(val: T): asserts val is NonNullable<T> {
if (val === undefined || val === null) {
throw new AssertionError(
`Expected 'val' to be defined, but received ${val}`
);
}
}
此外還有其它新特性與特性增強,詳情查看更新說明:
https://devblogs.microsoft.com/typescript/announcing-typescript-3-7
https://www.typescriptlang.org/play/index.html?#show-whatisnew 推薦閱讀
總結
以上是生活随笔為你收集整理的TypeScript 3.7稳定版发布的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL Server 中 JSON_MO
- 下一篇: .NET手撸绘制TypeScript类图