Stack Exchange
Class implements interface in typescirpt
I was wondering why does not typescript compiler throw error on code below:
interface Greetings {
    greeting: string;
}

class Human implements Greetings {
    greeting: string = "Why hello there";
}

class Lion implements Greetings {
    greeting: string = "Roar";
}

class Lemon {
    greeting: string = "I'M A LEMON";
}

class LivingSpecies {
    private species: Greetings;

    public greet() {
        console.log(this.species.greeting)
    }

    constructor(species: Greetings) {
        this.species = species;
    }
}

const species1 = new LivingSpecies(new Human())
species1.greet(); // "Why hello there"

const species2 = new LivingSpecies(new Lion())
species2.greet(); // "Roar"

const species3 = new LivingSpecies(new Lemon()) // Why compiler does not complain here?
species3.greet(); // "I'M A LEMON" <--- Why?

For the first two cases it works as intended, both classes implement Greetings interface, and LivingSpecies constructor requires class that implements it. But Lemon class "passes" the constructor parameter as if it implements Greetings interface. Could you explain this? Thank you.

I'm assuming you expect this because you're used to languages which use nominal subtyping - i.e T is assignable to U if and only if T explicitly extends U. In typescript you have structural subtyping - i.e T is assingable to U if U's properties are a subset of T's. This means that two objects with the same properties are considered the same type. You can read more here on how this works in TS here https://www.typescriptlang.org/docs/handbook/type-compatibility.html

@mbdavis so, structural subtyping is like relying on signature and not on the type name?

exactly! as to the why - does this answer your question? https://stackoverflow.com/questions/55180304/why-does-typescript-allow-for-subtyping

Well, your comment already answered my question xd. Thank you. And yes, marked as duplicate.
