美文网首页
TypeScript 代码整洁之道 - 格式化

TypeScript 代码整洁之道 - 格式化

作者: 小校有来有去 | 来源:发表于2019-03-02 13:04 被阅读11次

将 Clean Code 的概念适用到 TypeScript,灵感来自 clean-code-javascript
原文地址: clean-code-typescript
中文地址: clean-code-typescript

简介

image

这不是一份 TypeScript 设计规范,而是将 Robert C. Martin 的软件工程著作 《Clean Code》 适用到 TypeScript,指导读者使用 TypeScript 编写易读、可复用和易重构的软件。

格式化

就像这里的许多规则一样,没有什么是硬性规定,格式化也是。重点是不要争论格式,使用自动化工具实现格式化。对于工程师来说,争论格式就是浪费时间和金钱。通用的原则是保持一致的格式规则

对于 TypeScript ,有一个强大的工具叫做 TSLint。它是一个静态分析工具,可以帮助您显著提高代码的可读性和可维护性。项目中使用可以参考以下 TSLint 配置:

还可以参考TypeScript 风格指南和编码约定的源代码。

大小写一致

大写可以告诉你很多关于变量、函数等的信息。这些都是主观规则,由你的团队做选择。关键是无论怎么选,都要一致

反例:


const DAYS_IN_WEEK = 7;

const daysInMonth = 30;

const songs = ['Back In Black', 'Stairway to Heaven', 'Hey Jude'];

const Artists = ['ACDC', 'Led Zeppelin', 'The Beatles'];

function eraseDatabase() {}

function restore_database() {}

class animal {}

class Container {}

正例:


const DAYS_IN_WEEK = 7;

const DAYS_IN_MONTH = 30;

const SONGS = ['Back In Black', 'Stairway to Heaven', 'Hey Jude'];

const ARTISTS = ['ACDC', 'Led Zeppelin', 'The Beatles'];

function eraseDatabase() {}

function restoreDatabase() {}

class Animal {}

class Container {}

类名、接口名、类型名和命名空间名最好使用“帕斯卡命名”。

变量、函数和类成员使用“驼峰式命名”。

调用函数的函数和被调函数应靠近放置

当函数间存在相互调用的情况时,应将两者靠近放置。最好是应将调用者写在被调者的上方。这就像读报纸一样,我们都是从上往下读,那么读代码也是。

反例:


class PerformanceReview {

  constructor(private readonly employee: Employee) {

  }

  private lookupPeers() {

    return db.lookup(this.employee.id, 'peers');

  }

  private lookupManager() {

    return db.lookup(this.employee, 'manager');

  }

  private getPeerReviews() {

    const peers = this.lookupPeers();

    // ...

  }

  review() {

    this.getPeerReviews();

    this.getManagerReview();

    this.getSelfReview();

    // ...

  }

  private getManagerReview() {

    const manager = this.lookupManager();

  }

  private getSelfReview() {

    // ...

  }

}

const review = new PerformanceReview(employee);

review.review();

正例:


class PerformanceReview {

  constructor(private readonly employee: Employee) {

  }

  review() {

    this.getPeerReviews();

    this.getManagerReview();

    this.getSelfReview();

    // ...

  }

  private getPeerReviews() {

    const peers = this.lookupPeers();

    // ...

  }

  private lookupPeers() {

    return db.lookup(this.employee.id, 'peers');

  }

  private getManagerReview() {

    const manager = this.lookupManager();

  }

  private lookupManager() {

    return db.lookup(this.employee, 'manager');

  } 

  private getSelfReview() {

    // ...

  }

}

const review = new PerformanceReview(employee);

review.review();

组织导入

使用整洁且易于阅读的import语句,您可以快速查看当前代码的依赖关系。导入语句应遵循以下做法:

  • Import语句应该按字母顺序排列和分组。
  • 应该删除未使用的导入语句。
  • 命名导入必须按字母顺序(例如:import {A, B, C} from 'foo';)。
  • 导入源必须在组中按字母顺序排列。 例如: import * as foo from 'a'; import * as bar from 'b';
  • 导入组用空行隔开。
  • 组内按照如下排序:
    • Polyfills (例如: import 'reflect-metadata';)
    • Node 内置模块 (例如: import fs from 'fs';)
    • 外部模块 (例如: import { query } from 'itiriri';)
    • 内部模块 (例如: import { UserService } from 'src/services/userService';)
    • 父目录中的模块 (例如: import foo from '../foo'; import qux from '../../foo/qux';)
    • 来自相同或兄弟目录的模块 (例如: import bar from './bar'; import baz from './bar/baz';)

反例:

import { TypeDefinition } from '../types/typeDefinition';
import { AttributeTypes } from '../model/attribute';
import { ApiCredentials, Adapters } from './common/api/authorization';
import fs from 'fs';
import { ConfigPlugin } from './plugins/config/configPlugin';
import { BindingScopeEnum, Container } from 'inversify';
import 'reflect-metadata';

正例:

import 'reflect-metadata';

import fs from 'fs';
import { BindingScopeEnum, Container } from 'inversify';

import { AttributeTypes } from '../model/attribute';
import { TypeDefinition } from '../types/typeDefinition';

import { ApiCredentials, Adapters } from './common/api/authorization';
import { ConfigPlugin } from './plugins/config/configPlugin';

使用 typescript 别名

为了创建整洁漂亮的导入语句,可以在tsconfig.json中设置编译器选项的pathsbaseUrl属性。

这样可以避免导入时使用较长的相对路径。

反例:

import { UserService } from '../../../services/UserService';

正例:

import { UserService } from '@services/UserService';
// tsconfig.json
...
  "compilerOptions": {
    ...
    "baseUrl": "src",
    "paths": {
      "@services": ["services/*"]
    }
    ...
  }
...

上一章:TypeScript 代码整洁之道- 错误处理
下一章:TypeScript 代码整洁之道- 注释

相关文章

网友评论

      本文标题:TypeScript 代码整洁之道 - 格式化

      本文链接:https://www.haomeiwen.com/subject/efyeuqtx.html