TypeScript中的接口和类

use*_*696 21 javascript interface typescript

在C#中,接口和类之间存在巨大差异.实际上,类表示引用类型,因此我们实际上可以创建在该类上建模的对象,而接口则是类签名的合同,以确保存在某种行为.特别是我们无法创建接口实例.

接口的全部意义在于暴露行为.类通过给出所述行为的一个显式实现来实现它.

在这种情况下,尽管接口可能包含属性,但由于行为问题,我们大多数时候都关心接口.所以大多数类型,接口只是行为契约.

另一方面,在TypeScript上,我看起来让我感到非常不安,事实上我不止一次看过这个,这就是这个问题的原因.

在一个教程中我看到了这个:

export interface User {
    name: string; // required with minimum 5 chracters
    address?: {
        street?: string; // required
        postcode?: string;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是等一下.为什么User是界面?如果我们认为像C#,User不应该是一个接口.事实上,看着它,似乎我们正在定义数据类型User,而不是行为契约.

像在C#中一样思考,自然就是这样:

export class User {
    public name: string;
    public address: Address;
}
export class Address {
    public street: string;
    public postcode: string;
}
Run Code Online (Sandbox Code Playgroud)

但是,像使用类一样使用接口来定义数据类型而不是定义行为契约这一点在TypeScript中似乎很常见.

那么TypeScript中的接口是什么意思?为什么人们在TypeScript中使用接口,就像我们在C#中使用clases一样?如何在TypeScript中正确使用接口:建立行为契约,或者定义属性和对象应该具有哪些?

dec*_*eze 26

考虑到在Javascript中,数据通常通过JSON交换为普通对象:

let data = JSON.parse(someString);
Run Code Online (Sandbox Code Playgroud)

假设这data是一个User对象数组,我们将它传递给一个函数:

data.forEach(user => foo(user))
Run Code Online (Sandbox Code Playgroud)

foo 将输入如下:

function foo(user: User) { ... }
Run Code Online (Sandbox Code Playgroud)

但是等等,我们什么都没做new User!我们应该吗?我们是否应该编写一个类User及其map所有data内容,即使结果完全相同,也可以Object使用属性?不,这只是为了满足类型系统而疯狂,但不会改变运行时的任何内容.一个简单的interface描述了具体的对象是如何有望像(以"行为")是完全足够了这里.

  • 是的,`data.forEach(foo)`...我只是为了清晰而使用了简写.:O) (2认同)
  • @ASolvent动力是一把双刃剑……用简单的界面来输入对象的鸭子很棒,但是通过上下文隐式转换简单类型可能是一个陷阱。您想找到一个快乐的媒介:必要时使用钉子类型,足够时使用鸭子型。 (2认同)

Joe*_*ins 13

我也从C#背景来到Typescript并且想知道同样的事情.我正在考虑POCO(POTO是一件事吗?)

那么TypeScript中的接口是什么意思?

Typescript手册似乎说接口用于" 在代码中定义合同 ".

为什么人们在TypeScript中使用接口,就像我们在C#中使用类一样?

我同意@ deceze的答案.

John Papa在他的博客上扩展了类和接口的主题.他建议类最适合"创建多个新实例,使用继承,[和]单例对象".因此,根据Typescript手册中描述的Typescript接口的意图和一个人的意见,似乎没有必要在Typescript中建立合同.相反,您应该使用接口.(你的C#意识仍然会被冒犯.)

接口应该在TypeScript中正确使用:建立行为契约,或者定义属性和对象应该有哪些?

如果我理解这个问题,你问的接口应建立合同的行为合同结构.对此,我会回答:两者.Typescript接口仍然可以像在C#或Java中使用接口一样使用(即描述类的行为),但它们也提供了描述数据结构的能力.

此外,我的同事让我使用类而不是接口,因为接口在编译器中不产生代码.

例:

这个打字稿:

class Car implements ICar {
    foo: string;
    bar(): void {
    }
}

interface ICar {
    foo: string;
    bar(): void;
}
Run Code Online (Sandbox Code Playgroud)

产生这个Javascript:

var Car = (function () {
    function Car() {
    }
    Car.prototype.bar = function () {
    };
    return Car;
}());
Run Code Online (Sandbox Code Playgroud)

试试看


Mat*_*247 10

打字稿中的接口类似于C#中的接口,因为它们都提供合同.但是,与仅包含方法的C#接口相反,typescript接口也可以描述对象包含的字段或属性.因此,它们也可以用于C#接口无法直接使用的东西.

typescript中接口和类之间的主要区别在于接口没有运行时表示,并且不会为它们发出任何代码.接口非常广泛可用.例如,您可以使用对象文字来构造满足接口的对象.喜欢:

let user: User = {
  name: 'abc',
  address: {
    street: 'xyz',
  },
};
Run Code Online (Sandbox Code Playgroud)

或者您可以将任何数据对象(例如通过JSON解析接收)分配给接口(但是您的预检查应该断言它确实是有效的数据).因此,接口对数据非常灵活.

另一方面,类具有在运行时与它们相关联的类型,并且生成了代码.您可以在运行时检查类型,instanceof并设置原型链.如果定义User为类,除非调用构造函数,否则它将不是有效用户.而且你不能只定义任何类型的合适数据User.您需要创建一个新实例并复制属性.

我个人的经验法则:

  • 如果我正在处理纯数据(不同来源)我使用接口
  • 如果我正在建模具有身份和状态的东西(并且可能附加了修改状态的方法),我正在使用一个类.