美文网首页
TypeScript 代码整洁之道 - 对象和数据结构

TypeScript 代码整洁之道 - 对象和数据结构

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

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

    简介

    image

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

    对象和数据结构

    使用getterssetters

    TypeScript 支持 getter/setter 语法。使用 getter 和 setter 从对象中访问数据比简单地在对象上查找属性要好。原因如下:

    • 当需要在获取对象属性之前做一些事情时,不必在代码中查找并修改每个访问器。
    • 执行set时添加验证更简单。
    • 封装内部表示。
    • 更容易添加日志和错误处理。
    • 可以延迟加载对象的属性,比如从服务器获取它。

    反例:

    
    class BankAccount {
    
      balance: number = 0;
    
      // ...
    
    }
    
    const value = 100;
    
    const account = new BankAccount();
    
    if (value < 0) {
    
      throw new Error('Cannot set negative balance.');
    
    }
    
    account.balance = value;
    
    

    正例:

    
    class BankAccount {
    
      private accountBalance: number = 0;
    
      get balance(): number {
    
        return this.accountBalance;
    
      }
    
      set balance(value: number) {
    
        if (value < 0) {
    
          throw new Error('Cannot set negative balance.');
    
        }
    
        this.accountBalance = value;
    
      }
    
      // ...
    
    }
    
    const account = new BankAccount();
    
    account.balance = 100;
    
    

    让对象拥有 private/protected 成员

    TypeScript 类成员支持 public(默认)protected 以及 private的访问限制。

    反例:

    
    class Circle {
    
      radius: number;
    
      
    
      constructor(radius: number) {
    
        this.radius = radius;
    
      }
    
      perimeter(){
    
        return 2 * Math.PI * this.radius;
    
      }
    
      surface(){
    
        return Math.PI * this.radius * this.radius;
    
      }
    
    }
    
    

    正例:

    
    class Circle {
    
      constructor(private readonly radius: number) {
    
      }
    
      perimeter(){
    
        return 2 * Math.PI * this.radius;
    
      }
    
      surface(){
    
        return Math.PI * this.radius * this.radius;
    
      }
    
    }
    
    

    不变性

    TypeScript 类型系统允许将接口、类上的单个属性设置为只读,能以函数的方式运行。

    还有个高级场景,可以使用内置类型Readonly,它接受类型 T 并使用映射类型将其所有属性标记为只读。

    反例:

    
    interface Config {
    
      host: string;
    
      port: string;
    
      db: string;
    
    }
    
    

    正例:

    
    interface Config {
    
      readonly host: string;
    
      readonly port: string;
    
      readonly db: string;
    
    }
    
    

    类型 vs 接口

    当可能需要联合或交集时,请使用类型。如果需要扩展实现,请使用接口。然而,没有严格的规则,只有适合的规则。

    详细解释参考关于 Typescript 中typeinterface区别的解答

    反例:

    
    interface EmailConfig {
    
      // ...
    
    }
    
    interface DbConfig {
    
      // ...
    
    }
    
    interface Config {
    
      // ...
    
    }
    
    //...
    
    type Shape {
    
      // ...
    
    }
    
    

    正例:

    
    type EmailConfig {
    
      // ...
    
    }
    
    type DbConfig {
    
      // ...
    
    }
    
    type Config  = EmailConfig | DbConfig;
    
    // ...
    
    interface Shape {
    
    }
    
    class Circle implements Shape {
    
      // ...
    
    }
    
    class Square implements Shape {
    
      // ...
    
    }
    
    

    上一章:TypeScript 代码整洁之道 - 函数
    下一章:TypeScript 代码整洁之道 - 类

    相关文章

      网友评论

          本文标题:TypeScript 代码整洁之道 - 对象和数据结构

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