我通读了TypeScript Coding guidelines

我觉得这句话相当令人费解:

不要使用"I"作为接口名称的前缀

我的意思是,如果没有"I"前缀,这样的事情就没有多大意义

class Engine implements IEngine

我是不是漏掉了什么明显的东西?

另一件我不太明白的事是:

Classes

为了保持一致性,不要在核心编译器管道中使用类.使用

这是否说明我根本不应该使用类?

希望有人能帮我澄清:)

推荐答案

当一个团队/公司发布一个框架/编译器/工具集时,他们已经有了一些经验,一套最佳实践.他们分享它作为指导方针.指南是recommendations.如果你不喜欢任何东西,你可以无视它们.

这就是为什么TypeScript团队不推荐I个前缀接口的原因.

Reason #1 The times of the Hungarian notation have passed

I prefix for interface supporters的主要论点是,前缀有助于立即搜索(窥视)类型是否为接口.前缀有助于立即摸索(偷看)的说法吸引了Hungarian notation人.I表示接口名称的前缀,C表示类,A表示抽象类,s表示字符串变量,c表示常量变量,i表示整数变量.我同意这样的名称修饰可以为您提供类型信息,而无需将鼠标悬停在标识符上或通过热键导航到类型定义.这个微小的好处被下面提到的Hungarian notation个缺点和其他原因所抵消.匈牙利符号在当代框架中没有使用.由于历史原因(COM),C#有I个前缀(这是C#中唯一的前缀).回想起来,这是其中之一.NET architects(布拉德·艾布拉姆斯饰)认为这样会更好.TypeScript是COM遗留免费的,因此它没有I前缀作为接口规则.

Reason #2 I-prefix violates encapsulation principle

假设你有黑匣子.你得到了一些类型参考,可以让你和那个盒子互动.您不应该关心它是一个接口还是一个类.你只需要使用它的界面部分.要求知道它是什么(接口、特定实现或抽象类)违反了封装.

示例:假设您需要修复代码中的API Design Myth: Interface as Contract,例如删除ICar接口,使用Car基类.然后,您需要在所有消费者中执行此类更换.I前缀导致消费者对黑盒实现细节的隐式依赖.

原因#3防止不良命名

开发人员懒得正确思考名称.命名是Two Hard Things in Computer Science项中的一项.当开发人员需要提取接口时,只需在类名中添加字母I,就可以得到接口名.不允许为接口使用I前缀迫使开发人员绞尽脑汁为接口 Select 合适的名称. Select 的名字不仅在前缀上应该不同,而且强调意图的不同.

抽象情况:不应该定义ICar接口和相关的Car类.Car是一个抽象概念,应该是用于合同的抽象概念.实现应该有描述性的、独特的名称,例如SportsCar, SuvCar, HollowCar.

好例子:WpfeServerAutosuggestManager implements AutosuggestManagerFileBasedAutosuggestManager implements AutosuggestManager.

坏例子:AutosuggestManager implements IAutosuggestManager.

Reason #4 Properly chosen names vaccinate you against API Design Myth: Interface as Contract.

在我的实践中,我遇到了很多人,他们在一个单独的接口中不经意地复制了类的接口部分,该接口有Car implements ICar个命名方案.在单独的接口类型中复制类的接口部分并不会神奇地将其转换为抽象.您仍将获得具体的实现,但使用了重复的接口部分.如果你的抽象不是很好,复制接口部分无论如何也不会改善它.提取抽象是一项艰巨的工作.

注意:在TS中,模拟类或重载功能不需要单独的接口.

export class SecurityPrincipalStub implements Required<SecurityPrincipal> {
  public isFeatureEnabled(entitlement: Entitlement): boolean {
      return true;
  }
  public isWidgetEnabled(kind: string): boolean {
      return true;
  }

  public areAdminToolsEnabled(): boolean {
      return true;
  }
}

如果要构造一个不包含某些公共成员的类型,那么可以使用combination of Omit and Exclude.

Typescript相关问答推荐

如何将http上下文附加到angular中翻译模块发送的请求

Typescript对每个属性具有约束的通用类型

如何在ts中使用函数重载推断参数类型

React-Native运行方法通过监听另一个状态来更新一个状态

带有联合参数的静态大小数组

需要使用相同组件重新加载路由变更数据—React TSX

为什么typescript要把这个空合并转换成三元?

TypeScript Page Routing在单击时不呈现子页面(React Router v6)

隐式键入脚本键映射使用

路由链接不会导航到指定router-outlet 的延迟加载模块

是否有一个版本的联合类型递归地使属性只出现在一个可选选项中?

在Mac和Windows上运行的Web应用程序出现这种对齐差异的原因是什么?(ReactNative)

对象类型的TypeScrip隐式索引签名

如何将对象数组中的键映射到另一种对象类型的键?

带投掷的收窄类型

如何键入派生类的实例方法,以便它调用另一个实例方法?

使用强类型元组实现[Symbol.iterator]的类型脚本?

如何从抽象类的静态方法创建子类的实例?

Select 类型的子项

typescript如何从映射类型推断