Typescript 接口和类之间的差异

类型脚本接口和类之间的区别是什么? 我什么时候使用 我什么时候使用接口? 它们的优点是什么?

我需要为后端服务器的 http 请求创建一些类型(使用 Angular 2) ,比如: },

"fields": {
"project": {
"id": "10000"
},
"summary": "something's wrong",
"issuetype": {
"id": "10000"
},
"assignee": {             // not neccesary required
"name": "homer"
},
"reporter": {
"name": "smithers"
},
"priority": {            // not neccesary required
"id": "20000"
}
}

我应该用什么来建立这些模型? 谢谢!

39251 次浏览

根据 角度2型指南推荐使用 ClassInterface打字。主要区别在于,编译时 class将持久化,而 Interface则完全删除,因为它们不提供任何用法。

只需要在整个项目中保持一致,并且更喜欢使用 class的样式指南方法,谁知道呢,也许有一天您需要将 method添加到您的 models中。

查看下面的答案了解更多细节: https://stackoverflow.com/a/55505227/5463904

使用类型脚本来创建数据模型而不是类,因为编译器在运行时不会为接口生成任何相应的 JavaScript 代码。然而,如果你使用一个类仅仅是为了建立一个数据模型,那么编译器将为它创建相应的 JS 代码,因此将消耗内存。

来自 Angular 风格指南的一个片段: https://angular.io/guide/styleguide#interfaces

”考虑使用类而不是服务和 声明(组件、指令和管道)。”

考虑为数据模型使用接口。

在过去的两年里,我使用了角度,简单的说,当我想添加任何行为到我的对象时,我使用类,例如,在任何类中,我想添加返回已处理数据的 get 方法,当没有行为添加到对象时,我想直接访问对象时,我将使用接口。. 使用类如果您定义构造函数,您限制用户定义某个变量,以便在构造任何对象之前进行初始化。

SimpleClass 用于创建对象,Interface 帮助您确定这些对象应该包含哪些内容。

类就像一个蓝图/模板,我们可以使用它来创建对象。 接口类似于一个约定,类必须就该约定达成一致,以实现该接口或定义此蓝图应包含的内容。

一个简单的类:

class Car {
engine: string; // 'var' is not used;


constructor(engine: string) { // This is how we create constructor
this.engine = engine;
}


display(): void { // 'function' keyword is not used here.
console.log(`Engine is ${this.engine}`); // just a log.
}
}


var objCar = new Car('V8'); // creates new onject
objCar.display(); // output: Engine is V8
console.log(objCar.engine); // output: V8 (accessing member here)

一个简单的界面:

    interface IPerson { // This is how we create an interface.
firstName: string, // use commas to separate.
lastName: string, // In classes we use semi-colon to separate.
displayDetails: (number) => string
}


// We are going to store 'interface object' in a variable.
// i.e. we are implementing interface with variable(not class!!)
var customer: IPerson = {


firstName: 'jose jithin', // 'implements' variables
lastName: 'stanly',


// Now method implementation.
// Note: the syntax of 'displayDetails' maybe a bit confusing (given below)
// as two colons are used.
// It specifies a return type(string) here for this method.
displayDetails: (rank): string => { return `This person has rank ${rank}. ` }


// It can be rewritten as following too.
displayDetails: (rank) => { return `This person has rank ${rank}. ` };
// i.e. return type need not be specified, just like a normal method definition syntax.
}


console.log(customer.firstName); // output: jose jithin


console.log(customer.lastName);  // output: stanly


console.log(customer.displayDetails(1)); // output: This person has rank

我有详细的类和接口与我的 文章。这可能有助于你了解。

2019年: 差异和使用情况更新

首先,有一个明显的区别: 语法。这是一个简单但必要的理解差异: 接口属性可以以逗号或分号结束,但是类属性只能以分号结束。有趣的是。关于何时使用和不使用的部分可能是主观的——这些是我给团队成员的指导方针,但是其他团队可能会出于合理的原因而有其他的指导方针。如果你的团队有不同的做法,请随意评论,我很想知道为什么。

接口 : 允许定义将在设计和编译时用于强类型的类型。它们可以“实现”或“扩展”,但不能实例化(您不能 new它们)。它们在向下传输到 JS 时被删除,所以它们不占用空间,但是在运行时也不能检查它们的类型,所以你不能检查一个变量是否在运行时实现了一个特定的类型(例如 foo instanceof bar) ,除非检查它的属性: 接口类型检查与类型脚本

何时使用接口 : 当您需要为一个对象创建属性和函数的契约时,使用它们,该对象将在代码中的多个位置使用,特别是多个文件或函数。另外,当您希望其他对象以这个基本属性集开始时,可以使用这个属性集,例如具有一个 Vehicle接口,多个类将其实现为特定类型的工具,如 CarTruckBoat(例如 class Car implements Vehicle)。

何时不使用接口 : 何时需要默认值、实现、构造函数或函数(不仅仅是签名)。

: 还允许定义将在设计和编译时用于强类型的类型,另外,还可以在运行时使用。这也意味着代码不会被编译出来,因此它会占用空间。这是@Sakuto 提到的一个关键区别,但是它不仅仅意味着空间。这意味着可以对类进行类型化检查,即使在已翻译的 JS 代码中也能保留对“它们是谁”的理解。进一步的区别包括: 类可以使用 new实例化,可以扩展,但不能实现。类可以具有构造函数和实际函数代码以及默认值。

何时使用类 : 当希望创建包含实际函数代码的对象时,需要一个用于初始化的构造函数,并且/或者希望使用 new创建它们的实例。此外,对于简单的数据对象,您可以使用类来设置默认值。另一个需要使用它们的时间是在进行类型检查的时候,但是如果需要的话还有一些接口的变通方法(请参阅接口部分的 OS 链接)。

不使用类 : 当你有一个简单的数据接口时,不需要实例化它,当你想让其他对象实现它,当你想简单地把一个接口放在一个现有的对象上(想想类型定义文件) ,或者当它将占用的空间是禁止的或不必要的。顺便说一句,如果你看的话。您将注意到,d.TS 文件只使用接口和类型,因此当传输到 TS 时,这将被完全删除。

最后注意 ,除了类和接口,还有其他两个选项,第一个是所谓的“ type”,它非常类似于接口,但请查看这篇 SO 文章,特别是2019年更新的答案: 接口与类型。最后一个选择是使用 TS 进行函数式编程(而不是 OOP)。

对于完整的故事与例子访问 Passionfordev.com和更好的阅读类与继承与例子访问 https://jameshenry.blog/typescript-classes-vs-interfaces/

我发现,当使用 classes 而不是 interface时,类型安全性不是很强,特别是在 React 中作为支撑传递的函数签名。

接口

  • 描述一个对象应该是什么样子
  • 仅存在编译时间,仅用于类型检查

课程

  • 用作实例化/生成对象的蓝图
  • 可以实现一个接口,这意味着它必须实现接口中至少所有的属性/方法

例如:

interface Person {
name: string;
id: number;
doStuff: () => void;
}


// implements Person says: You have to at least implement these things
// which are located on the person interface
class employee implements Person {
constructor(public name: string, public id: number){}


doStuff () {console.log('Doing stuff')}
}


// interfaces can also describe variables and parameters
const p1: Person = {
name: 'foo',
id: 34,
doStuff () {console.log('Doing stuff')}
}

所以在类和接口上有很多不同。

其中很少有:

定义
TypeScript 类是一个保存方法、变量并为对象提供框架的模板。 TypeScript 接口是一个蓝图,它告诉派生类要实现什么。

实际应用

类: 明智地设计模块功能框架
接口: 隐藏外部访问资源和保护核心逻辑的复杂性

实时的

类: 我们可以使用类的对象实例化类
接口: 我们不能实例化接口

你可以在 https://codetopology.com/scripts/typescript/typescript-interface-vs-class/找到更多的不同

TypeScript 中的接口有两个用途:

  1. 类的蓝图(例如,class Foo implements IFoo)
  2. “类型化对象”(例如 let foo: IFoo = { … })

1是“经典”的用途,在 Java,C # 等中可以看到: 接口只是描述类应该是什么样子。它不是直接实例化的。

至少我只在 TypeScript 中看到过 # 2: 它基本上是一个编译时检查的字典。

我的经验是,# 2会导致维护问题: 您今天创建的简单字典最终可能会用于方法,在这种情况下,您必须更改所有调用方,这扩大了测试范围。

我建议: 避免使用 公众人士中的模式 # 2,使用有利于类的模式。它可以作为内部编译时检查,但是通过方便地添加方法,将使代码未来的维护人员受益。当然,你可能永远不需要这些方法,但是当你需要的时候,你会很高兴你给自己留下了选择的余地。