繁体   English   中英

为什么对象接口定义类似于打字稿中的类接口定义

[英]Why a object interface define is similar to class interface define in typescript

我对打字稿很陌生,当我从它的操场上学习它的界面部分时,有一个困惑:

http://www.typescriptlang.org/Handbook#interfaces-our-first-interface-

http://www.typescriptlang.org/Handbook#interfaces-class-types

一个是在讨论如何定义对象的接口,一个是为类定义,但它们可以使用相似的结构,谁能指出为什么?

对象的接口,一个是为类定义的,但它们可以使用类似的结构,谁能指出为什么

object没有关于创建者的运行时知识。 而类实例知道它的构造函数。 这如下所示:

interface Foo {
    foo: number
}

let foo: Foo = { foo: 123 };

class Bar {
    bar: number;
}

let bar: Bar = new Bar(); 
bar.bar = 123;
console.log(bar instanceof Bar); // True  

这并没有改变打字稿是结构化的事实https://basarat.gitbook.io/typescript/content/docs/getting-started.html

类也可以为您的代码提供更好的结构:https ://basarat.gitbook.io/typescript/content/docs/classes.html

在这两种情况下,接口都具有相同的目的 - 应用类型限制/细化。 “对象的接口”和“(或应用于)类的接口”之间没有区别。

第一个例子展示了结构类型,没有引入类的概念:

任何具有类型一致结构的类型都满足接口契约1

.. 请注意,我们不必像在其他语言中那样明确说明传递给“printLabel”的 [匿名创建] 对象实现了此接口。 在这里,重要的是形状。 如果我们传递给函数的对象[可以静态证明满足][在接口中]列出的要求,那么它是允许的

实现接口的类的实例隐式地保证了这个契约。 将接口添加到类允许在类声明本身而不是仅在使用站点进行额外的约束检查:这可以实现更本地化和更有用的与类型相关的错误报告。


1这是静态/编译限制:对象的类型信息已从对象文字本身自动合成。 实际运行时值与证明类型正确性无关。

它们具有相似的结构,但以不同的方式使用。 该类允许您创建要在应用程序中使用的新对象。 接口告诉编译器应该如何构造事物。 下面你可以看到你可以给 label 属性添加一个值。 你不能用界面来做到这一点。

interface Something {
    label: string;
}

class Something {
    label: string = 'some string value';
}

在下面的示例中,接口强制Something类始终需要一个名为label的属性,并且类型需要是string 如果您一起更改类型或删除属性。 编译器会抱怨。

interface ISomething {
    label: string;
}

class Something implements ISomething {
    label: string = 'some string value';
}

在上面的示例中,我建议使用在接口名称前添加大写字母I的约定,以消除类和接口之间的混淆。


在下一个示例中,我们将使用一个接口 ( IUser ) 来允许将多个类传递到getUserDescription函数中,而编译器不会抱怨。 这称为多态性。 我们的函数不关心它是教师、学生还是任何其他类。 它只关心传入的结构是否与接口匹配。

interface IUser {
    firstName: string;
    lastName: string;
    type: string;
}

class Student {

    firstName: string = null;
    lastName: string = null;
    type: string = 'student';
    courses: Array<any> = [];

    constructor(firstName: string, lastName: string) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

class Teacher implements IUser {

    firstName: string = null;
    lastName: string = null;
    type: string = 'teacher';
    classes: Array<any> = [];

    constructor(firstName: string, lastName: string) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

const getUserDescription = (user: IUser): string => {
    return `${user.firstName} ${user.lastName} is a ${user.type}`;
};

getUserDescription(new Teacher('Harry', 'Jones')); // Harry Jones is a teacher
getUserDescription(new Student('Joe', 'Cool')); // Joe Cool is a student

如果你注意到上面的Teacher实现了IUserStudent没有。 您通常会以相同的方式完成,但我想表明您是否可以在类级别强制执行该结构。

查看我的文章http://www.codebelt.com/typescript/typescript-classes-object-oriented-programming/了解更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM