日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747


 

大家好,我是 Echa。

11 月 1 日,TypeScript 4.9 發布了候選版本 (RC),直到穩定版發布基本上不會有太大變化了,本次帶來的更新還是挺有意思的,下面我就跟大家來一起看一下~

新的 satisfies 操作符

在使用 TypeScript 類型推斷的時候,有很多情況下會讓我們面臨兩難的選擇:我們即希望確保某些表達式能夠匹配某些類型,但也希望保留這個表達式的特定類型用來類型推斷。

比如下面的例子,我們定義了一個顏色選擇對象:

const palette = { red: [255, 0, 0], green: "#00ff00", blue: [0, 0, 255] };

因為每個屬性都被賦予了默認值,ts 會自動幫我們自動推導 palette 的屬性類型,所以我們可以直接調用它們的方法:

// red 被推斷為 Number[] 類型 const a = palette.red.at(0); // green 被推斷為 string 類型 const b = palette.green.toUpperCase();

因為顏色都是固定的,我們想讓我們的 palette 對象擁有特定的幾個屬性,來避免我們寫出一些錯別字:

const palette = { // 錯別字:rad -> red rad: [255, 0, 0], green: "#00ff00", blue: [0, 0, 255] };

所以我們可能會為 palette 定義一個類型,這樣錯別字就會被檢測出來了:

type Colors = "red" | "green" | "blue"; type RGB = [red: number, green: number, blue: number]; const palette: Record = { rad: [255, 0, 0], // ~~~~ The typo is now correctly detected green: "#00ff00", blue: [0, 0, 255] };

但是這時候我們再調用 palette.red 的方法,你會發現 TS 的類型推斷會出錯:

type Colors = "red" | "green" | "blue"; type RGB = [red: number, green: number, blue: number]; const palette: Record = { red: [255, 0, 0], green: "#00ff00", blue: [0, 0, 255] }; // 'palette.red' "could" 的類型是 string | RGB ,所以它不一定存在 at 方法 const a = palette.red.at(0);

這就讓我們陷入了兩難的境地,我們用更嚴格了類型約束了寫出 bug 的可能性,但是卻失去了類型推斷的能力。

satisfies 關鍵字就是用來解決這個問題的,它既能讓我們驗證表達式的類型是否與某個類型匹配,也可以保留基于值進行類型推斷的能力:

type Colors = "red" | "green" | "blue"; type RGB = [red: number, green: number, blue: number]; const palette = { rad: [255, 0, 0], // 可以捕獲到錯別字 rad green: "#00ff00", blue: [0, 0, 255] } satisfies Record; // 都可以調用 const a = palette.red.at(0); const b = palette.green.toUpperCase(); in 操作符類型收窄優化

在日常開發中,我們經常需要處理一些在運行時不完全確定的值,比如我們現在有下面兩個類型:

interface Duck { quack(): string; } interface Cat { miao(): string; }

在實際使用過程中,TS 不能確定 value 是否是上面中哪一個類型,所以會拋出錯誤:

function main(value: Duck | Cat) { if (value.quack) { // roperty 'quack' does not exist on type 'Duck | Cat'. return value.quack; } }

我們可能會使用 in 這樣的關鍵字來實現簡單的類型收窄:

function main(value: Duck | Cat) { if ('quack' in value) { return value.quack; } }

也可以實現一個更通用的類型守衛,可以參考我這篇文章:什么是鴨子類型?

 

但是,這個寫法的前提是我們用到的對象有明確的類型,如果這個對象的屬性沒有明確的類型呢?我們來看看下面這段 JAVAScript 代碼:

function tryGetPackageName(context) { const packageJSON = context.packageJSON; // 檢查是否是個對象 if (packageJSON && typeof packageJSON === "object") { // 檢查是否存在一個字符串類型的 name 屬性 if ("name" in packageJSON && typeof packageJSON.name === "string") { return packageJSON.name; } } return undefined; }

把這段代碼重寫為規范的 TypeScript,我們只需要定義一個 Context 類型,但是由于 packageJSON 沒有明確的類型定義,再使用 in 進行類型收窄就有問題了:

interface Context { packageJSON: unknown; } function tryGetPackageName(context: Context) { const packageJSON = context.packageJSON; // 檢查是否是個對象 if (packageJSON && typeof packageJSON === "object") { // 檢查是否存在一個字符串類型的 name 屬性 if ("name" in packageJSON && typeof packageJSON.name === "string") { // ~~~~ // error! Property 'name' does not exist on type 'object. return packageJSON.name; // ~~~~ // error! Property 'name' does not exist on type 'object. } } return undefined; }

這是因為 in 操作符只會嚴格收窄到實際定義被檢查屬性的類型,所以 packageJSON 的類型從 unknown 收窄到了 object ,而 object 類型上不存在 name 屬性,就會引發報錯。

TypeScript 4.9 優化了這個問題,in 操作符更加強大了,它會被收窄為被檢查類型和 Record<"property-key-being-checked", unknown> 的交叉類型。。。

比如在上面的例子中,packageJSON 的類型會被收窄為 object & Record<"name",unknown>,這樣我們直接訪問 packageJSON.name 就沒問題了!

interface Context { packageJSON: unknown; } function tryGetPackageName(context: Context): string | undefined { const packageJSON = context.packageJSON; // 檢查是否是個對象 if (packageJSON && typeof packageJSON === "object") { // 檢查是否存在一個字符串類型的 name 屬性 if ("name" in packageJSON && typeof packageJSON.name === "string") { // 可以正常運行! return packageJSON.name; } } return undefined; }

TypeScript 4.9 還加強了一些關于如何使用 in 操作符的檢查,比如左側要檢查的屬性必須是 string | number | symbol 類型,而右側類型必須要可分配給 object。
accessor 關鍵字支持

 

accessor 是 ECMAScript 中即將推出的一個類關鍵字,TypeScript 4.9 對它提供了支持:

class Person { accessor name: string; constructor(name: string) { this.name = name; } }

accessor 關鍵字可以為該屬性在運行時轉換為一對 get 和 set 訪問私有支持字段的訪問器:

class Person { #__name: string; get name() { return this.#__name; } set name(value: string) { this.#__name = name; } constructor(name: string) { this.name = name; } } NaN 相等判斷警告

NaN 是一個特殊的數值,代表 “非數字” ,在 JS 中它和任何值相比較都是 false,包括它自己:

console.log(NaN == 0) // false console.log(NaN === 0) // false console.log(NaN == NaN) // false console.log(NaN === NaN) // false

相對應的,所有值都不等于 NaN

console.log(NaN != 0) // true console.log(NaN !== 0) // true console.log(NaN != NaN) // true console.log(NaN !== NaN) // true

這其實并不是 JavaScript 特有的問題,因為任何包含 IEEE-754 浮點數的語言都有相同的行為;但 JavaScript 的主要數字類型就是浮點數,并且 JavaScript 中的數字解析為 NaN 還挺常見的,所以在代碼中去比較值是否等于 NaN 的情況還挺普遍的。但是正確的做法應該是使用 Number.isNaN 函數來判斷。假如你不知道這個問題,就可能引發一些 bug。

在 TypeScript 4.9 中,如果你直接用一些值和 NaN 相比較,會拋出錯誤并提示你使用 Number.isNaN

function validate(someValue: number) { return someValue !== NaN; // ~~~~~~~~~~~~~~~~~ // error: This condition will always return 'true'. // Did you mean '!Number.isNaN(someValue)'? } return 關鍵字的定義

在編輯器中,當你對 return 關鍵字運行 go-to-definition 時,TypeScript 現在會自動跳轉到相應函數的頂部。這有助于我們快速了解 return 屬于哪個函數。

另外,TypeScript 會將此功能擴展到更多關鍵字,例如 await、yield、switch、case、default 等等。

最后

TypeScript 團隊最近還發布了 5.0 版本的迭代規劃(https://github.com/microsoft/TypeScript/issues/51362),這將是 TypeScript 的又一個大的版本,其中包含了很多有趣的想法,還是挺值得期待的!

更多詳細更新請查看 TypeScript 官方博客:https://devblogs.microsoft.com/typescript/announcing-typescript-4-9-rc/

你覺得上面哪些更新對你最有用呢?歡迎在評論區和我留言;如果這篇文章幫助到了你,歡迎點贊和關注。

分享到:
標簽:TypeScript
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定