angular - 合并带有方法的枚举
我发现将枚举与命名空间合并的做法非常有用。例如:
enum Status : {
OK = 1,
NOT_OK = 2,
}
namespace Status {
function Color(status : Status) {
if(status == Status.OK)
return 'green';
else
return 'red';
}
}
但是我发现 tslint 不喜欢它们……我可以使用其他哪些方法来获得相同的行为?我考虑过用带有静态方法的类来替换命名空间,但它有两个缺点:
1) 这个类必须换一个名字(例如 'StatusUtil')——好吧,我可以接受……
2) 当使用 Angular 时,‘StatusUtil’ 类(不像命名空间)不能直接从 HTML 文件调用——这意味着我必须在每个组件中编写额外的方法,类似这样:
getColor(status : Status) {
return StatusUtil(status);
}
我考虑的另一个选项是使用 Angular 的依赖注入而不是静态方法。你觉得哪种做法是最佳实践?
答案#1
我认为这是一个很好地压制 tslint 警告的案例。Tslint 是用来指出你代码中可能存在的问题的,但你可以在代码中使用注释来压制这些警告。
这条规则是为了防止使用命名空间来组织代码,但 Typescript 仍然有一些只能通过命名空间实现的合并场景。
直接来自 weswigham(TS 团队成员)在评论中说:
命名空间与类、函数和枚举合并是命名空间的“好”用法吗?
有时候——因为我们无法识别某些类型的静态属性的临时附加——在许多情况下,在函数或类静态上使用临时属性可能就足够了(除非你需要它包含类型)。不过,同样合理的是质疑你是否真的需要一开始就进行合并——例如,如果你想关联一个组件及其参数类型,仅从同一个模块导出它们两者岂不是就足够了吗?为什么还要把它们封装在命名空间中呢?那没有意义。
归结为这一点:
如果你正在考虑使用命名空间来组织代码:不要。模块已经取代了这个角色。如果你需要只有命名空间才能提供的功能:可以,但要检查是否可以在不使用命名空间的情况下同样表达该概念(例如,通过类的静态属性或函数属性,或者重新导出的模块)。在同一个项目中混用命名空间和模块也是不好的风格——这会让人感觉不自然,因为传统意义上命名空间的一个主要特性是跨文件作用域合并,而模块之间不存在这种情况(正如我所说,模块本身实际上就是一个命名空间)。
在那个讨论中,命名空间不会从语言中移除,所以在特定场景下使用它们是可以的。