“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”不應在類型交集中使用
相交類型將多種類型組合爲一種。這使你可以將現有類型加在一起,以獲得具有所需所有功能的單個類型。但是,具有沒有成員的類型的交集不會更改結果類型。相反,相交的使用 any
或never
作爲相交的一部分將始終導致any
或never
。幾乎可以肯定這是一個錯誤。
不兼容的代碼示例:
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
因此,catc
h除捕獲以外,捕獲其他內容的可能性較小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);
}
}