3

在实际的开发中,我们可能有如下场景:

  1. 有一个Student接口,用于与接口的返回类型相对应。
  2. 在一个StudentService,该方法中有一个update方法,用于更新Student.

情景回顾

Student:

interface Student {
  id: number;
  // 学号
  no: number;
  // 姓名
  name: string;
  // 手机号
  phone: string;
  // 性别
  sex: boolean;
}

现在逻辑是这样,在更新学生的信息时,我们仅允许用户更新name以及phone字段。此时我们想在StudentService.update方法中体现仅仅允许更新这两个字段,我们有两种写法:

第一种,直接将参数类型声明为Student:

class StudentService {
  void update(id: number, student: Student) {
  }
}

第二种,直接在参数中声明字段类型:

class StudentService {
  void update(id: number, student: {name: string, phone: string}) {
  }
}

弊端分析

第一种方法的弊端在于我们无法通过update方法的声明能直接得到该方法中更新学生的字段,但其优势在于可以快速的显示Student实体的变更,比如在后期中我们将phone字段变更为mobile

第二种方法的优势是可以在update方法直接得出要更新的字段,但弊端是无法快速的响应Student实体在日后的字段变更。

建议方案

其实我是想要一个类似于如下的参数声明:

class StudentService {
  void update(id: number, student: {name: string, phone: string} as Student) {
  }
}

但很遗憾的是typescript并不支持这种写法,那么退而求其次,我们可以这样写:

class StudentService {
  void update(id: number, student: {name: string, phone: string}) {
    student = student as Student;
  }
}

简单的在函数的第一行增加一个类型推导,这样一来:

  1. Student类型发生变更时,我们可以通过语法检查自动地发现该行代码发生了语法错误,进而进行修正。
  2. 由于在参数中我们直接声明了各个字段,而不是使用Student进行广泛的声明,我们可以直接获取到该update方法具体更新的功能。

潘杰
3.1k 声望238 粉丝