为什么Typescript类会自动实现接口?

AdH*_*nem 2 interface class typescript

所以我没有任何以前的JS经验就完成了Typescript教程.我的问题是在给定的示例代码中,为什么可以将Student对象传递给以Person作为参数的greeter()函数?Student类从不实现所述接口,所以我想知道在Typescript类中是否自动实现接口.如果他们这样做,这背后的原因是什么?如果Car,Plane和Student都自动实现Person,那似乎毫无用处.

class Student {
    fullName: string;
    constructor(public firstName, public middleInitial, public lastName) {
        this.fullName = firstName + " " + middleInitial + " " + lastName;
    }
}

interface Person {
    firstName: string;
    lastName: string;
}

function greeter(person : Person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}

var user = new Student("Jane", "M.", "User");

document.body.innerHTML = greeter(user);
Run Code Online (Sandbox Code Playgroud)

Tim*_*rry 8

这称为结构类型.从本质上讲,TypeScript中类型之间的关系永远不需要显式声明('命名',如在名义类型中,如C#,Java和朋友),它们纯粹是通过分析所涉及类型的结构来完成的.

在TypeScript中,当你说一个类实现一个接口时,你实际上根本没有改变它,或者所涉及的子类的类型,你只是要求编译器确认它确实已经实现了该接口.

至于推理,这里的关键因素(与TypeScript中的许多决定一样)是这与JavaScript在实践中更接近匹配(即鸭子打字 - 如果你传递正确的形状,它会工作),所以兼容性使用现有的JavaScript代码更容易.

值得注意的是,这确实使TypeScript有一些限制.例如,您不能使用相同但不兼容的类型作为标记接口来限制输入,就像在Java中一样.在Java中,SerializableCloneable cloneable是两个空接口,可以实现将类型标记为可序列化或可克隆,然后方法只接受Serializable参数以确保它们只获得明确知道序列化安全的类.在TypeScript中,您不能这样做:空接口不会更改对象的结构,因此根本不会对类型系统产生任何影响.