在TypeScript / Angular中什么时候使用Interface和Model

我最近看了一个关于使用TypeScript的Angular 2教程,但不确定什么时候用接口,什么时候用模型来处理数据结构。

接口示例:

export interface IProduct {
ProductNumber: number;
ProductName: string;
ProductDescription: string;
}

模型示例:

export class Product {
constructor(
public ProductNumber: number,
public ProductName: string,
public ProductDescription: string
){}
}

我想从URL加载JSON数据并绑定到接口/模型。有时我想要单个数据对象,有时我想保存对象的数组。

我应该使用哪一个,为什么?

161987 次浏览
接口描述了一个的契约或一个新的类型。 它是一个纯Typescript元素,所以它不会影响Javascript

模型,即,是一个实际的JS函数,用于生成新对象。

我想从URL加载JSON数据并绑定到接口/模型。

选择一个模型,否则它在Javascript中仍然是JSON。

使用类而不是接口这是我在所有研究后发现的。

为什么?单独的类比类加接口的代码要少。(无论如何,你可能需要一个类的数据模型)

为什么?类可以充当接口(使用实现而不是扩展)。

为什么?在Angular依赖注入中,接口类可以是提供者查找令牌。

< a href = " https://angular。/a> . io/guide/styleguide# Style -03-03" rel="nofollow noreferrer">from Angular Style guide

基本上,一个类可以做接口能做的所有事情。所以可能永远不需要使用接口

正如@ThierryTemplier所说,从服务器接收数据,并在组件之间传输模型(以保持智能感知列表并使设计时错误),使用接口是可以的,但我认为对于向服务器发送数据(DTO),最好使用类来利用从模型自动映射DTO的优势。

我个人在我的模型中使用接口,但是关于这个问题有3个学派,选择一个最常见的是基于你的需求:

1 -接口:

interface是TypeScript上下文中唯一的存在的一个虚拟结构。TypeScript编译器使用接口仅仅是为了进行类型检查。一旦你的代码被转译为目标语言,它就会从接口中剥离出来——JavaScript没有类型。

interface User {
id: number;
username: string;
}
// inheritance
interface UserDetails extends User {
birthdate: Date;
biography?: string;  // use the '?' annotation to mark this property as optionnal
}

如果你使用Angular 4.3使用HttpClientModule中的HttpClient,那么映射服务器对interface的响应是直接的。X及以上。

getUsers() :Observable<User[]> {
return this.http.get<User[]>(url); // no need for '.map((res: Response) => res.json())'
}

何时使用接口:

  • 您只需要服务器数据的定义,而不会为最终输出引入额外的开销。
  • 你只需要传输数据,不需要任何行为或逻辑(构造函数初始化、方法)
  • 你不经常从接口实例化/创建对象
    • 使用简单的对象-文字表示法__abc0,你可能会到处都是半实例。
    • 它不会强制执行类所给出的约束(构造函数或初始化逻辑、验证、私有字段的封装……等等)
  • 您需要为系统定义契约/配置(全局配置)

2 -类:

class定义对象的蓝图。它们表示这些对象将继承的逻辑、方法和属性。

class User {
id: number;
username: string;
constructor(id :number, username: string)  {
this.id = id;
this.username = username.replace(/^\s+|\s+$/g, ''); // trim whitespaces and new lines
}
}
// inheritance
class UserDetails extends User {
birthdate: Date;
biography?: string;
constructor(id :number, username: string, birthdate:Date, biography? :string )  {
super(id,username);
this.birthdate = ...;
}
}

何时使用类:

  • 您实例化您的类,并随着时间的推移更改实例状态。
  • 类的实例需要一些方法来查询或改变它的状态
  • 当你想将行为与数据更紧密地联系起来时;
  • 在创建实例时强制执行约束。
  • 如果您在类中只编写了一堆属性赋值,则可以考虑使用类型。

2 -类型:

随着typescript的最新版本,接口和类型变得越来越相似。 types不表示应用程序内部的逻辑或状态。当您想要描述某种形式的信息时,最好使用类型。它们可以描述不同形状的数据,从简单的结构,如字符串、数组和对象。 和接口一样,类型只是虚拟结构,不会被编译成任何javascript,它们只是帮助编译器让我们的工作更简单
type FamilySituation = 'single' | 'married' | 'divorced' | 'widow' ;...
type User = {
id: number;
username: string;
}
// inheritance
type UserDetails = User & {
birthDate: Date;
familySituation: FamilySituation ;
}

何时使用类型:

  • 将其作为简洁的函数参数传递
  • 描述一个类构造函数参数
  • 记录从API输入或输出的小型或中型对象。
  • 它们不代表状态和行为
为了使你的代码更灵活,我们需要使用接口。 创建接口并在类的构造函数中传递接口类型。

好处:

  1. 如果接口参数有变化,则不需要改变类。 2.为了测试,你可以在类的构造函数中使用模拟数据

当您只是想检查数据类型以确保响应始终具有必要的键时,请使用interface。类/模型不仅仅用于检查数据类型。另外,很高兴知道javascript中不存在接口,这意味着typescript将总是在编译时处理接口,不选择javascript原生的类。