所以我没有任何以前的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);
答案 0 :(得分:8)
这称为Structural Typing。从本质上讲,TypeScript中类型之间的关系永远不需要显式声明('命名',如在名义输入中,如C#,Java和朋友),它们纯粹是通过分析所涉及类型的结构来完成的。
在TypeScript中,如果你说一个类实现了一个接口,你实际上根本没有更改类,或者所涉及的子类的类型,你只是要求编译器确认它确实已经实现了接口
至于推理,这里的关键因素(与TypeScript中的许多决策一样)是,它更接近于JavaScript在实践中所做的事情(即duck typing - 如果你传递的是正确的形状,它会工作),因此更容易与现有的JavaScript代码兼容。
值得注意的是,这确实会使TypeScript受到一些限制。例如,您不能像marker interfaces那样使用相同但不兼容的类型来限制输入,就像在Java中一样。在Java Serializable和Cloneable中,cloneable是两个空接口,可以实现将类型标记为可序列化或可复制,然后方法只接受Serializable
参数,以确保它们只获取类明确地知道序列化是安全的。在TypeScript中,您不能这样做:空接口不会更改对象的结构,因此根本不会对类型系统产生任何影响。
答案 1 :(得分:4)
接口是纯粹的抽象概念 在真正的javascript世界中,它没有界面概念。 你用打字稿写的界面不会被翻译成javascript
因此,对于界面,它不必真正实现它,只需要具有相同的形状。 官方解释可以在这里找到 https://www.typescriptlang.org/docs/handbook/type-compatibility.html