TypeScript規則知多少

“await” 只能和 promises一起使用

可以await在非Promise的值上使用,但它是無用的且具有誤導性。await是暫停執行,直到Promise的異步代碼運行完畢。

不兼容的代碼示例:

let x = 42;
await x; // Noncompliant

合規解決方案:

let x = new Promise(resolve => resolve(42));
await x;

let y = p ? 42 : new Promise(resolve => resolve(42));
await y;

“ for of”應與Iterables一起使用

如果你有一個可迭代的對象(例如數組,集合或列表),那麼遍歷其值的最佳選擇是for of語法。使用計數器,然後……你將獲得正確的行爲,但是你的代碼看起來並不那麼幹淨。

不兼容的代碼示例:

const arr = [4, 3, 2, 1];

for (let i = 0; i < arr.length; i++) {  // Noncompliant
  console.log(arr[i]);
}

合規解決方案:

const arr = [4, 3, 2, 1];

for (let value of arr) {
  console.log(value);
}

不應使用“模塊”

每個文件都被視爲“外部”模塊。module關鍵字的使用創建了一個內部模塊,並且namespace出於相同目的在ECMAScript 2015添加之前使用了該關鍵字。現在namespace可以使用了,module 因爲它可以做相同的事情,所以不贊成使用它,並且使用它會使維護人員不瞭解該語言的歷史。

不兼容的代碼示例:

module myMod {  // Noncompliant
  // ...
}

合規解決方案:

namespace myMod {
  // ...
}

使用“ Array.prototype.sort()”時應提供比較功能

無論數組中的類型如何,默認的排序順序都是字母順序,而不是數字順序。具體來說,即使數組僅包含數字,數組中的所有值也將轉換爲字符串並按字典順序排序,順序如下:1、15、2、20、5

幸運的是,該sort方法允許你傳遞可選的compare函數以指定排序順序。提供比較功能時,返回的順序取決於比較功能的返回值。

不兼容的代碼示例:

var myarray = [80, 3, 9, 34, 23, 5, 1];

myarray.sort();
console.log(myarray); // outputs: [1, 23, 3, 34, 5, 80, 9]

合規解決方案:

var myarray = [80, 3, 9, 34, 23, 5, 1];

myarray.sort((a, b) => (a - b));
console.log(myarray); // outputs: [1, 3,  5, 9, 23, 34, 80]

方法重載應分組在一起

爲了清楚起見,應將同一方法的所有重載分組在一起。這樣,用戶和維護人員都可以快速瞭解所有當前可用的選項。

不兼容的代碼示例:

interface MyInterface {
  doTheThing(): number;
  doTheOtherThing(): string;
  doTheThing(str: string): string;  // Noncompliant
}

合規解決方案:

interface MyInterface {
  doTheThing(): number;
  doTheThing(str: string): string;
  doTheOtherThing(): string;
}

僅在構造函數中或聲明時分配的私有屬性應爲“只讀”

readonly屬性只能在類構造函數中或在聲明時分配。如果類具有未標記的屬性,readonly而僅在構造函數中設置,則可能導致對該屬性的預期用途產生混淆。爲避免混淆,應標記此類屬性readonly以明確其預期用途,並防止將來的維護人員無意中更改其用途。

不兼容的代碼示例:

class Person {
  private _birthYear: number;  // Noncompliant
  constructor(birthYear: number) {
    this._birthYear = birthYear;
  }
}

合規解決方案:

class Person {
  private readonly _birthYear: number;
  constructor(birthYear: number) {
    this._birthYear = birthYear;
  }
}

包裝器對象不應用於基本類型

將包裝對象用於原始類型是無償的,令人困惑的和危險的。如果使用包裝對象構造函數進行類型轉換,則只需刪除new關鍵字,即可自動獲得原始值。如果使用包裝對象作爲向基元添加屬性的方法,則應重新考慮設計。此類使用被認爲是不良做法,應予以重構。

不兼容的代碼示例:

let x = new Number("0");
if (x) {
  alert('hi');  // Shows 'hi'.
}

合規解決方案:

let x = Number("0");
if (x) {
  alert('hi');
}

沒有成員的類型,“ any”和“ never”不應在類型交集中使用

相交類型將多種類型組合爲一種。這使你可以將現有類型加在一起,以獲得具有所需所有功能的單個類型。但是,具有沒有成員的類型的交集不會更改結果類型。相反,相交的使用 anynever作爲相交的一部分將始終導致anynever。幾乎可以肯定這是一個錯誤。

不兼容的代碼示例:

function foo(p: MyType & null) { // Noncompliant
 // ...
}

function bar(p: MyType & any) { // Noncompliant
 // ...
}

合規解決方案:

function foo(p: MyType | null) {
 // ...
}
// or
function foo(p: MyType & AnotherType) {
 // ...
}

function bar(p: any) {
 // ...

不應使用“any”類型

變量可以聲明爲帶或不帶類型。如果聲明中包含初始化,則聲明爲無類型的變量將被隱式鍵入,並且編譯器類型檢查將自動應用於任何類型的變量。但是,如果你使用any“類型” 聲明變量, 則你已明確告訴編譯器不要進行任何類型檢查,這是有風險的。

不兼容的代碼示例:

let a = 42;  // implicitly typed to number
let b: number = 42;  // explicitly typed to number
let c: any = 42;  // Noncompliant

合規解決方案:

let a = 42;
let b: number = 42;
let c: number = 42;

promise reject不應被“try”阻止捕獲

由於執行的異步特性,reject由promise拋出的異常(包括)將不會被嵌套try塊捕獲。而是使用catchof方法Promise或將其包裝在awaitexpression中。

try-catch語句只包含對返回的函數的調用(Promise因此,catch除捕獲以外,捕獲其他內容的可能性較小Promise)。

不兼容的代碼示例:

function runPromise() {
  return Promise.reject("rejection reason");
}

function foo() {
  try { // Noncompliant, the catch clause of the 'try' will not be executed for the code inside promise
    runPromise();
  } catch (e) {
    console.log("Failed to run promise", e);
  }
}

合規解決方案:

function foo() {
  runPromise().catch(e => console.log("Failed to run promise", e));
}

// or
async function foo() {
  try {
    await runPromise();
  } catch (e) {
    console.log("Failed to run promise", e);
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章