typescript Angular:类和接口
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/54356711/
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
Angular : Class and Interface
提问by Scieur Arnaud
I'm here today because I've a question about, like the title said, about classes and interfaces in Angular.
我今天在这里是因为我有一个问题,就像标题所说的,关于Angular 中的类和接口。
From my Point of View, I understand this:
从我的角度来看,我是这么理解的:
Interfacesare used in Typescript to perform type-checking, they are here until the transpilationand disappear in the production. Also Interface cannot be used to instantiate.
接口在 Typescript 中用于执行类型检查,它们一直存在,直到转译并在生产中消失。接口也不能用于实例化.
Classescame from ES6 are also used for type-checking, but they stay after transpilation and generate codein the production. Also, they are used to instantiate.
来自 ES6 的类也用于类型检查,但它们在编译后保留并在生产中生成代码。此外,它们用于实例化。
So, basically, Interface is useful if we don't need them in production, if we only need to type-check. On the opposite, Class are here if we need them in production, particularly for the instantiation.
所以,基本上,如果我们在生产中不需要它们,如果我们只需要类型检查,Interface 很有用。相反,如果我们在生产中需要它们,尤其是实例化,Class 就在这里。
I am Correct or Did I miss something about class and interface?
我是对的还是我错过了关于类和界面的一些东西?
回答by mwilson
You're correct. Interfaces are great when you only need the type checking whereas classes are great when you not only want the type checking, but you need some methods or require some other logic.
你是对的。当您只需要类型检查时,接口很棒,而当您不仅需要类型检查,而且需要一些方法或需要一些其他逻辑时,类也很棒。
Personally, I always start with just using an interface, and once I need some methods, I'll add a class and inherit the interface. I would also add that I prefer to alwayshave an interface whether you're using a class or not. This allows you to pass around/inject the interface instead of having to re-instantiate class multiple times.
就我个人而言,我总是从只使用接口开始,一旦我需要一些方法,我就会添加一个类并继承该接口。我还要补充一点,无论您是否使用类,我都更喜欢始终拥有一个接口。这允许您传递/注入接口,而不必多次重新实例化类。
Here is an example of a typical pattern I would follow if I need some methods (which means I need a class
)
这是一个典型模式的示例,如果我需要一些方法(这意味着我需要一个class
)
interface IPerson {
firstName: string;
lastName: string;
age: number;
getFullName(): string;
}
class Person implements IPerson {
public firstName: string;
public lastName: string;
public age: number;
constructor(firstName: string, lastName: string, age: number) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
getFullName(): string {
return `${this.firstName} ${this.lastName}`
}
}
const person: IPerson = new Person('John', 'Doe', 44);
I would never inject or need to import Person
anywhere unless I actually needed to 'new up' a new person. I can always inject IPerson
instead and so long as what was passed in as the class, the interface will allow me call all the class methods and access the properties as I wish.
我永远不会注入或需要在Person
任何地方导入,除非我真的需要“更新”一个新人。我总是可以注入IPerson
,只要作为类传入的内容,接口将允许我调用所有类方法并根据需要访问属性。
However, sometimes I don't need methods, but I need a data contract (or just want to suppress TypeScript from being pissed off I'm not telling it what everything is):
然而,有时我不需要方法,但我需要一个数据契约(或者只是想抑制 TypeScript 被激怒我没有告诉它一切是什么):
interface IPerson {
firstName: string;
lastName: string;
age: number;
}
const person: IPerson = <IPerson>{
firstName: 'John',
lastName: 'Doe',
age: 44
};
Doing it this way still gives you a wayto create a variable on the fly that adheres to the interface. However, there are no methods when you do it this way (so you lose your getFullName
function and would have to run that manually)
这样做仍然为您提供了一种动态创建符合界面的变量的方法。但是,当您这样做时没有任何方法(因此您失去了getFullName
功能并且必须手动运行)
Overall, I find myself using interfaces on http returns that are structured json. I don't really need to do anything more to them on the front end as the backend has done the heavy lifting for me already. So, creating a class for each one of those returns may be overkill, but some people prefer it that way.
总的来说,我发现自己在结构化 json 的 http 返回上使用接口。我真的不需要在前端对他们做任何更多的事情,因为后端已经为我完成了繁重的工作。因此,为每个返回值创建一个类可能有点矫枉过正,但有些人更喜欢这样。
One other thing to bring up is that creating all these models is extremely time consuming. It pays off though. In one of my projects, I used an npm module to automatically generate TypeScript interfaces based off my c# models. That saved a ton of typing and thought it was pretty cool (https://www.npmjs.com/package/csharp-models-to-typescript)
要提出的另一件事是创建所有这些模型非常耗时。不过还是有回报的。在我的一个项目中,我使用 npm 模块根据我的 c# 模型自动生成 TypeScript 接口。这节省了大量的打字时间,并认为它很酷(https://www.npmjs.com/package/csharp-models-to-typescript)
One other popular solution is to use Swagger Codegen. You can 'swaggerize' your backend and have swagger codegen just generate your models and services for you. It's pretty slick. Here's an example repousing Angular and C# as the backend.
另一种流行的解决方案是使用Swagger Codegen。您可以“大摇大摆”您的后端,并让 swagger 代码生成器为您生成模型和服务。它很光滑。这是一个使用 Angular 和 C# 作为后端的示例存储库。
In general, it's really your preference. Just keep in mind, if you need methods and extra layers to build out a given model, a class is best. If you just need types and don't care about the rest of the fancy 'syntactical sugar' just use an interface. As you mentioned, interfaces disappear in production so it's certainly a plus.
一般来说,这真的是你的喜好。请记住,如果您需要方法和额外的层来构建给定的模型,类是最好的。如果您只需要类型而不关心其他花哨的“语法糖”,只需使用接口即可。正如您所提到的,接口在生产中消失了,所以这当然是一个加分项。
回答by DeborahK
Since you also tagged Angular in your question, I wanted to add to the answer from an Angular perspective.
由于您还在问题中标记了 Angular,我想从 Angular 的角度添加到答案中。
Angular also uses the Interface (or class) as a structure when retrieving data via http.
当通过 http 检索数据时,Angular 也使用接口(或类)作为结构。
export interface Product {
id: number;
productName: string;
productCode: string;
tags?: string[];
price: number;
description: string;
imageUrl: string;
}
@Injectable({ providedIn: 'root' })
export class ProductService {
private productsUrl = 'api/products';
constructor(private http: HttpClient) { }
getProducts(): Observable<Product[]> {
return this.http.get<Product[]>(this.productsUrl);
}
}
The http.get
method gets the data and populates the provided product
array structure. This makes it mucheasier to work with the data from the component.
该http.get
方法获取数据并填充提供的product
数组结构。这使得很多工作更容易从组件的数据。