定义一个表示星期的枚举后,如果还想提供“判断某天是否为工作日”的函数,可以把它组织到枚举名下,像 Weekday.isBusinessDay(day) 这样调用。

TypeScript 支持将枚举与同名 namespace 合并。利用这个特性,就能给枚举添加类似静态方法的成员。

用同名 namespace 扩展枚举

先声明 Weekday,再声明同名的 namespace,把相关函数放进去:

enum Weekday {
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday,
  Sunday,
}

namespace Weekday {
  export function isBusinessDay(day: Weekday) {
    switch (day) {
      case Weekday.Saturday:
      case Weekday.Sunday:
        return false
      default:
        return true
    }
  }
}

const mon = Weekday.Monday
const sun = Weekday.Sunday

console.log(Weekday.isBusinessDay(mon)) // true
console.log(Weekday.isBusinessDay(sun)) // false

调用时,枚举值和相关操作都通过 Weekday 访问:Weekday.Monday 表示星期一,Weekday.isBusinessDay() 负责判断。

什么时候值得这样组织

如果函数专门处理这个枚举,把它放在枚举名下,调用时比较容易发现,也能看出两者的关系。若函数涉及多个业务对象,或者项目本来就统一使用独立工具函数,继续单独定义函数也很自然。

另外,day: Weekday 是编译期的类型约束,不会自动检查运行时传入的数据。这个例子的 default 会对周末以外的值返回 true;如果参数来自接口或用户输入,需要先验证它确实是合法的枚举值。

同样的合并机制也能用于类和函数,可以在 TypeScript 官方的声明合并文档中继续查看。