2
votes

So I did the Typescript tutorial without any former JS experience. My question is in given example code, why can you pass the Student object into the greeter() function which takes a Person as parameter? The class Student never implements said interface so I wonder if in Typescript classes automatically implement interfaces. And if they do, what's the reasoning behind this? It seems pretty useless if Car, Plane and Student all automatically implement 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);
2
Answer to short to be an answer: Yes - Ryan Cavanaugh
What's the purpose of that? So every single class - f.ex. Car, Plane, Account - that I would declare in this file would implement Person??? I could as well just remove the interface completely and include it in the class then - AdHominem
You still have to have the same fields (of the same type) as the interface declares! Unless your Plane has a firstName and a lastName, it won't be considered a valid Person - Ryan Cavanaugh
Typescript interfaces are implemented structurally so a class only implements Person if it has firstName and lastName properties of type string. - Lee
The public keywords in front of the parameter names turns them into fields. The lack of type annotation means they're of type any; fields of type any are compatible with any other type. - Ryan Cavanaugh

2 Answers

9
votes

This is called Structural Typing. Essentially, relationships between types in TypeScript are never required to be explicitly declared ('named', as in nominal typing, like C#, Java and friends), they're done purely by analysing the structure of the types involved.

In TypeScript when you say that a class implements an interface, you're not actually changing the class at all, or the types of the subclasses involved, you're just asking the compiler to confirm that it does indeed already implement that interface.

As for the reasoning, the key factor here (as with many decisions in TypeScript) is that this more closely matches what JavaScript does in practice (i.e. duck typing - if you pass something the right shape, it'll work), so makes compatibility with existing JavaScript code far easier.

Notably this does leave TypeScript with some limitations. For example, you can't use identical but incompatible types as marker interfaces to limit input, as in Java. In Java Serializable and Cloneable cloneable are two empty interfaces which can be implemented to mark a type as serializable or cloneable, and methods can then accept only Serializable parameters to ensure they get only classes which are explicitly known to be safe to serialize. In TypeScript, you can't do that: an empty interface doesn't change the structure of an object, so doesn't make any difference to the type system at all.

4
votes

interface in typescript is a pure abstract concept in really javascript world, it doesn't has interface concept. the interface you write in typescript won't be translated into javascript

So, for interface, it doesn't have to really implement it, just need to be in the same shape. official explanation can be find here https://www.typescriptlang.org/docs/handbook/type-compatibility.html