Typescript 中接口和类的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40973074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between interfaces and classes in Typescript
提问by Emre ?ztürk
what is the different bewtween Typescript Interfaces and Classes? When do I use Class? When do I use Interfaces? What are the advantages of them?
Typescript 接口和类之间有什么不同?我什么时候使用类?我什么时候使用接口?它们的优点是什么?
I need to create some kind of types for an http-request to my backend server (Doing it with Angular 2), like : },
我需要为后端服务器的 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"
}
}
What should I use for building these models? Thank you!
我应该使用什么来构建这些模型?谢谢!
回答by Jeremy
2019: Update on Differences and Usages
2019 年:差异和用法更新
First, there is the obvious difference: syntax. This is a simple, but necessary to understand difference: Interface properties can end in commas or semi-colons, however class properties can only end in semi-colons. Now the interesting stuff. The sections about when to use and not to use may be subjective - these are the guidelines I give people on my team, but it is possible that other teams will have other guidelines for valid reasons. Feel free to comment if your team does it differently, I would love to learn why.
首先,有一个明显的区别:语法。这是一个简单但必须理解的区别:接口属性可以以逗号或分号结尾,但是类属性只能以分号结尾。现在是有趣的东西。关于何时使用和不使用的部分可能是主观的——这些是我给我团队中的人的指导方针,但其他团队可能会出于正当理由制定其他指导方针。如果您的团队有不同的做法,请随时发表评论,我很想知道原因。
Interfaces: Allow for defining a type that will be used during design and compile time for strong typing. They can be "implemented" or "extended" but cannot be instantiated (you can't new
them). They get removed when transpiling down to JS so they take up no space, but they also cannot be type checked during runtime, so you can't check if a variable implements a specific type at runtime (e.g. foo instanceof bar
), except by checking the properties it has: Interface type check with Typescript.
接口:允许定义将在设计和编译期间用于强类型的类型。它们可以被“实现”或“扩展”,但不能被实例化(你不能new
)。它们在转换为 JS 时被删除,因此它们不占用空间,但它们也不能在运行时进行类型检查,因此您无法在运行时检查变量是否实现了特定类型(例如foo instanceof bar
),除非通过检查它的属性具有:使用 Typescript 进行接口类型检查。
When to use interfaces: Use them when you need to create a contract of the properties and functions for an object that will be used in more than one place in your code, especially more than one file or function. Also, use when you want other objects to start with this base set of properties, such as having a Vehicle
interface that multiple classes implement as specific types of vehicles, like Car
, Truck
, Boat
(e.g. class Car implements Vehicle
).
何时使用接口:当您需要为一个对象创建属性和函数的契约时使用它们,该对象将在代码中的多个位置使用,尤其是多个文件或函数。此外,当您希望其他对象以该基本属性集开始时使用,例如具有Vehicle
多个类实现为特定类型车辆的接口,例如Car
, Truck
, Boat
(eg class Car implements Vehicle
)。
When not to use interfaces: When you want to have default values, implementations, constructors, or functions (not just signatures).
何时不使用接口:当您想要拥有默认值、实现、构造函数或函数(不仅仅是签名)时。
Classes: Also allow for defining a type that will be used during design and compile time for strong typing, and, additional, can be used during runtime. This also means that the code is not compiled out, so it will take up space. This is one key difference mentioned by @Sakuto, but has more implications than just space. It means that classes can be typed checked, retaining the understanding of "who they are" even in the transpiled JS code. Further differences include: classes can be instantiated using new
and can be extended, but not implemented. Classes can have constructors and actual function code along with default values.
类:还允许定义将在设计和编译期间用于强类型的类型,此外,还可以在运行时使用。这也意味着代码没有编译出来,所以会占用空间。这是@Sakuto 提到的一个主要区别,但其含义不仅仅是空间。这意味着可以检查类的类型,即使在转译的 JS 代码中也能保留对“它们是谁”的理解。进一步的差异包括:类可以使用实例化new
和扩展,但不能实现。类可以具有构造函数和实际函数代码以及默认值。
When to use classes: When you want to create objects that have actual function code in them, have a constructor for initialization, and/or you want to create instances of them with new
. Also, for simple data objects, you can use classes for setting up default values. Another time you would want to use them is when you are doing type checking, though there are workarounds for interfaces if needed (see the interface section OS link).
何时使用类:当您想创建包含实际功能代码的对象时,需要有一个用于初始化的构造函数,和/或您想使用new
. 此外,对于简单的数据对象,您可以使用类来设置默认值。另一个你想使用它们的时候是在你进行类型检查时,尽管如果需要,有接口的解决方法(请参阅接口部分 OS 链接)。
When not to use classes: When you have a simple data interface, do not need to instantiate it, when you want to have it implemented by other objects, when you want to simply put an interface on an existing object (think type definition files) or when the space it would take up is prohibitive or unwarranted. As a side note, if you look in .d.ts files you will notice that they only use interfaces and types, and thus this is completely removed when transpiled to TS.
何时不使用类:当您有一个简单的数据接口时,不需要实例化它时,当您希望它由其他对象实现时,当您只想将接口放在现有对象上时(想想类型定义文件)或者当它占用的空间令人望而却步或没有根据时。作为旁注,如果您查看 .d.ts 文件,您会注意到它们仅使用接口和类型,因此在转换为 TS 时将完全删除。
Final note, there are two other options than just classes and interfaces, the first is something called a "type", which is pretty similar to an interface, but check this SO post, specifically the 2019 Update answer: Typescript: Interfaces vs Types. The last option is to go functional programming style (not OOP) with TS.
最后要注意的是,除了类和接口之外,还有其他两个选项,第一个是称为“类型”的东西,它与接口非常相似,但请查看此 SO 帖子,特别是 2019 年更新答案:Typescript: Interfaces vs Types。最后一个选择是使用 TS 使用函数式编程风格(而不是 OOP)。
For the full story with examples visit PassionForDev.comand more good reading on classes vs. inheritance with examples visit https://jameshenry.blog/typescript-classes-vs-interfaces/.
有关示例的完整故事,请访问PassionForDev.com,更多关于类与继承的优秀阅读示例请访问https://jameshenry.blog/typescript-classes-vs-interfaces/。
回答by Sakuto
According to Angular 2 styleguideit's recommended to use Class
over Interface
for the typing. The main difference is that class
will persist when compiled while Interface
are purely removed since they do not serve any usage.
根据Angular 2 样式指南,建议使用Class
overInterface
进行打字。主要区别在于class
编译时将持续存在,而Interface
被完全删除,因为它们没有任何用途。
Just stay consistent over the whole project, and prefer the styleguide approach with class
, who know, maybe one day you will need to add method
to your models
.
仅仅停留在整个项目一致,并且喜欢与风格指南的做法class
,谁知道,也许有一天,你将需要添加method
到您的models
。
Check answer below for more details: https://stackoverflow.com/a/55505227/5463904
查看下面的答案以获取更多详细信息:https: //stackoverflow.com/a/55505227/5463904
回答by Jose
Simply Class is to create objects and Interface assists you what these objects should contain.
简单的类是创建对象,接口帮助你这些对象应该包含什么。
Class is like a blueprint/template using which we can create objects. Interface is like a contract on which a Class has to agree on to implement that Interface or define what this blueprint should contain.
类就像一个蓝图/模板,我们可以使用它来创建对象。接口就像一个契约,类必须在该契约上达成一致以实现该接口或定义此蓝图应包含的内容。
A simple class:
一个简单的类:
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)
A simple Interface:
一个简单的界面:
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
I have detailed on Class and Interface with my article. This might help you to understand.
我在我的文章中详细介绍了类和接口。这可能有助于您理解。
回答by Abhishek
Use typescript for making a Data model instead of class as compiler will not generate any corresponding JavaScript code for an interface at run time. Whereas if you use a class for merely making a data model then compiler will create corresponding JS code for it hence will consume memory.
使用 typescript 来创建数据模型而不是类,因为编译器不会在运行时为接口生成任何相应的 JavaScript 代码。而如果您使用一个类仅用于创建数据模型,那么编译器将为它创建相应的 JS 代码,因此会消耗内存。
A snippet from Angular's style guide: https://angular.io/guide/styleguide#interfaces
Angular 风格指南的片段:https: //angular.io/guide/styleguide#interfaces
"Consider using a class instead of an interface for services and declarables (components, directives, and pipes)."
"Consider using an interface for data models."
“考虑对服务和可声明对象(组件、指令和管道)使用类而不是接口。”
“考虑使用数据模型的接口。”
回答by Kushagra Misra
I am using angular past 2 years and in simple words when I want to add any behavior to my object I use class for example in any class I want to add get method which return processed data, and when there is no behavior added to object and I want to directly access object I will use interface.. Using class if you define constructor you restrict user to define certain variable to initialized before constructing any object.
我在过去 2 年中使用 angular,简单地说,当我想向我的对象添加任何行为时,我在任何类中使用类,例如,我想添加返回处理数据的 get 方法,并且当没有行为添加到对象和我想直接访问对象,我将使用接口。如果你定义构造函数,你会限制用户在构造任何对象之前定义某些变量来初始化。
回答by slimeygecko
I have found that type safety is not as strong when using class
es instead of interface
s, specifically with function signatures that are passed as a prop in React.
我发现当使用class
es 而不是interface
s时,类型安全性没有那么强,特别是在 React 中作为 prop 传递的函数签名。