Angular:类和接口

Sci*_*aud 9 class typescript

我今天在这里,是因为我有一个问题,如标题所述,关于Angular中的类和接口

从我的角度来看,我理解:

Typescript中使用了接口来进行类型检查,这些接口一直存在,直到进行编译并在生产中消失为止。接口也不能用于实例化

来自ES6的也用于类型检查,但它们会在编译后保留并在生产中生成代码。同样,它们用于实例化。

因此,基本上,如果我们在生产中不需要它们,而仅需要类型检查,则Interface是有用的。相反,如果我们在生产中需要它们(特别是用于实例化),则可以在这里使用Class。

我是正确的,还是我错过了有关类和接口的知识?

Deb*_*ahK 25

由于您还在问题中标记了 Angular,我想从 Angular 的角度添加到答案中。

当通过 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

http.get方法获取数据并填充提供的product数组结构。这使得很多工作更容易从组件的数据。

  • 我知道我去演出已经迟到了,但为什么不去上课呢?特别是如果您最终会提供与“Product”或“Products”数组交互的方法,例如对数组中的字段求和等。或者大部分操作应该在后端 API 上完成吗?我一直在纠结何时在 Angular 应用程序中使用类,因为大多数开发人员似乎认为接口是首选构造。 (2认同)
  • 现在 Angular v12 默认情况下具有严格的类型,类将要求*每个*字段都初始化为某些内容。接口不需要这样。此外,当执行上述代码时,它不会为每个检索到的项目创建 Product 类的实例。相反,是将他们“塑造”成班级的形状。因此,如果您定义了方法,那么如果不首先将返回的数据对象映射到从 Product 类创建的对象中,您将无法调用它们。欲了解更多信息:/sf/ask/3623462181/ (2认同)

mwi*_*son 19

没错 当您只需要类型检查时,接口就很棒;而当您不仅需要类型检查,还需要某些方法或其他逻辑时,类就非常有用。

就个人而言,我总是从仅使用接口开始,一旦我需要一些方法,便会向其添加一个类。我还要补充一点,无论您是否使用类,我个人都希望始终有一个接口。这使您可以传递/注入接口,而不必多次重新实例化类。

这是一个典型模式的示例,如果需要一些方法,我将按照该模式进行操作(这意味着我需要一个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);
Run Code Online (Sandbox Code Playgroud)

Person除非我确实需要“结识”一个新人,否则我永远不会注入或进口任何东西。我总是可以IPerson代替注入,只要在类中传入了什么,接口就可以允许我调用所有类方法并按需要访问属性。

但是,有时我不需要方法,但是我需要数据协定(或者只是想抑制TypeScript惹恼我,我没有告诉它一切是什么:

interface IPerson {
    firstName: string;
    lastName: string;
    age: number;
}

const person: IPerson = <IPerson>{
    firstName: 'John',
    lastName: 'Doe',
    age: 44
};
Run Code Online (Sandbox Code Playgroud)

这样做,这样还为您提供了一种方式来动态创建一个变量,它符合接口。但是,以这种方式进行操作时没有方法(因此,您将失去getFullName功能,必须手动运行该函数`

总的来说,我发现自己在结构化json的http返回上使用接口。我真的不需要在前端对他们做任何事情,因为后端已经为我完成了繁重的工作。因此,为这些收益中的每个收益创建一个类可能是过大的,但是有些人更喜欢这种方式。

要提出的另一件事是创建所有这些模型非常耗时。虽然有回报。在我的一个项目中,我使用了一个npm模块根据我的c#模型自动生成TypeScript接口。这样节省了大量的输入,并认为它很酷(https://www.npmjs.com/package/csharp-models-to-typescript

通常,这实际上是您的偏好。请记住,如果您需要方法和额外的层来构建给定的模型,则最好使用类。如果您只需要类型,而不关心其余的“语法糖”,请使用一个接口。正如您提到的,接口在生产中会消失,因此肯定是一个加号。

https://jsfiddle.net/mswilson4040/3vznkbq0/7/

  • 从技术上讲你可以做到这一点。然而,在上述场景中,模型的“额外逻辑”不会 ping 服务器或发出任何 http 请求。IMO 服务应保留用于服务器通信/全局功能(例如发射器等)。实际的数据契约(模型/接口)应该与服务隔离。该服务的工作应该严格是 http 请求,并作为“数据合同警察”,确保从服务器/http 请求返回的任何数据都融入您的模型中。显然,有多种方法可以做到这一点 (2认同)