天天看點

Hegel:勵志成為最好的 JavaScript 靜态類型檢查器

雲栖号資訊:【 點選檢視更多行業資訊

在這裡您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!

Hegel 作為 JavaScript 類型檢查器中的新秀,勵志要成為最好的 JavaScript 靜态類型檢查器。它宣稱提供了一個具備強類型推斷的可靠的類型系統。目前 Hegel 還在 alpha 測試階段,大家可以在其提供的專用線上練習場進行功能體驗。

Hegel 是一個類型注解可選的 JavaScript 類型檢查器,同時它和 TypeScript 一樣,使用者不需要重新學習一門新的語言結構,隻需要掌握注解的文法。Hegel 希望通過強大的、穩定的類型系統,盡量避免程式在運作時由于類型錯誤産生的異常。下面的代碼展示了其強大的類型檢查能力:

// 定義 numbers 的類型為 Array<number>
const numbers: Array<number> = [];
// 将 numbers 變量指派給 numbersOrStrings, 但其類型為 Array<string | number>
// Hegel 會檢查出類型錯誤:
// HegelError:類型 "Array<number>" 和類型 "Array<number | string>" 不相容
const numbersOrStrings: Array<string | number> = numbers;
// 給 numbersOrStrings 第二個元素指派
numbersOrStrings[1] = "Hello, TypeError!";
// 下面的代碼 Hegel 會檢查出類型異常:
// HegelError: 屬性 "toFixed" 在 "Number | undefined" 中不存在
numbers[1].toFixed(1);           

上面的代碼使用 TypeScript(v3.8.3)進行編譯時沒有任何錯誤,但是在實際運作時确會抛出異常。

譯者注:

JS 運作時,numbers 和 numbersOrStrings 都是引用類型。他們在互相指派的時候,屬于引用指派。是以 numbersOrStrings 修改元素内容的時候,對 numbers 也同樣有效果。是以在執行 numbers[1].toFixed(1) 時候,就會報錯,因為字元串沒有 toFixed 函數。上面的代碼展現了 Hegel 可靠的類型系統。

除了可靠的類型系統,健壯的類型推斷也是 Hegel 的主要設計目标。示例代碼如下:

// Hegel 會推斷 "promisify" 是 "<_q, _c>((_c) => _q) => (_c) => Promise<_q>"
const  promisify = fn => arg => Promise.resolve(fn(arg));
// 這裡,Hegel 會推斷為 "<_c>(_c) => Promise<_c>" 
const id =  promisify(x  => x)
// 同樣,"upperStr" 會被推斷為 "Promise<string>"
const upperStr = id("It will be inferred").then(str => str.toUpperCase()
// 最後 "twiceNum" 将會被推斷為 "Promise<number>"
const twicedNum =  id(42).then(num  => num **  2);             

而在TypeScript(測試版本:3.7.5)中運作相同的代碼時,TS 會識别3 個異常,同時會将變量 result推斷為Promise類型。 是以健壯的類型推斷允許開發人員盡量少的編寫代碼注釋,這樣反而更有利于代碼的可讀性。

Hegel 将異常也納入了類型檢查中,示例代碼如下:

function  assert(age)  {
  if  (typeof age !==  "number")  {
    throw  new  TypeError("Age is not number.");
  }  
  if  (age <=  0)  {
    throw  new  ReferenceError("Age can't be less or equals zero.");
  }
}
try  {
  assert(0);
}  catch(error)  {
  // 這裡的 "error" 變量,被推斷為 "ReferenceError | TypeError | unknown"
}           

Hegel 的缺點是不支援強制類型轉換和any類型,示例如下:

// Error: Hegel 中不存在 any 類型
const something:  any  =  null;
// Error: Hegel 中不支援類型轉換
(null:  any).call();           

在 Hegel 文檔中說明了其與主流類型檢查器(TypeScript 和 Flow)的對比。除了支援标準類型(基礎類型、函數、對象、類、數組)之外,Hegel 的類型系統還支援了未知類型(例如由 JSON.parse() 傳回的類型)、可選類型、聯合類型、元祖類型、類型别名、泛類型和可變類型。這也是 Hegel 的特性之一。

可變類型可以幫助我們從現有類型提取或者建立新類型。是以,可變類型可以了解為從一個類型生成另一個類型的函數。在 Hegel 中,定義了 17 個可變類型。

下面是可變類型 $Exclude (語義上和 TypeScript 中的 Exclude 類型類似)的示例代碼:

// 定義類型
type  Status  =  "Ok"  |  "Failed"  |  "Pending"  |  "Canceled";
// 使用 可變類型之後
// IntermediateStatuses = "Canceled" | "Panding"
type  IntermediateStatuses  = $Exclude<Status,  "Ok"  |  "Failed">;
// 指派
const intermediateStatuses:  Array<$Exclude<Status,  "Ok"  |  "Failed">>  =  ["Pending",  "Canceled"];
// Hegel 類型檢查異常:
// Error: 類型 "['Failed']" 和類型 "...Array<'Canceled' | 'Pending'>" 不相容
intermediateStatuses.push("Failed");           

parceljs 的作者,Devon Govett 在 Twitter 上感慨說:

Hegel 看上去很有趣,它比 TS 更接近 Flow,而且是使用 JS 實作的。專注于類型推斷和健壯類型,隻有 JS 和類型 (沒有額外的功能)。支援.d.ts、vscode 內建,等等…。

Hegel 釋出在 npm 上,提供了一個指令行工具和一個可互動的線上體驗區。同時,其在 GitHub 倉庫提供了對應的安裝指令,要求 node.js 最低版本為 12。

Hegel 是基于 MIT 協定的。歡迎大家在該項目的 GitHub 上進行回報和貢獻。另外,Hegel 的作者也聲明:

Hegel 源于社群,奉獻社群;是以,你的任何 PRs 和 issues 都不會被忽略和遺忘。

【雲栖号線上課堂】每天都有産品技術專家分享!

課程位址:

https://yqh.aliyun.com/zhibo

立即加入社群,與專家面對面,及時了解課程最新動态!

【雲栖号線上課堂 社群】

https://c.tb.cn/F3.Z8gvnK

原文釋出時間:2020-05-29

本文作者: Bruno Couriol

本文來自:“

InfoQ

”,了解相關資訊可以關注“

繼續閱讀