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);
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章