RandomB
RandomB

Reputation: 3749

How exactly does work inheritance of a class by an interface?

I am reading this section of the TypeScript handbook and I am playing with modified example:

class Control {
    public state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Checkbox implements SelectableControl {
    public state: any;
    select() { }
}

This code is fine. But Q1. I am not sure why I need to declare the property state in the Checkbox class since it exists already in the SelectableControl interface, really, why?

More interesting things happen when I change the access modifiers. If I change it of the state property (in the Control and the Checkbox) to protected:

class Control {
    protected state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Checkbox implements SelectableControl {
    protected state: any;
    select() { }
}

then I get an error "Class "Checkbox" implements interface "SelectableControl" wrongly. The property "state" is protected, but the type "Checkbox" is not a class, inherited from "Control" class" (it's a translation to English). Q2. What is the problem? Why I should inherit Control class if the state is already here, in the SelectableControl? How is it related to access modifier?!

And now I change protected to private:

class Control {
    private state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Checkbox implements SelectableControl {
    private state: any;
    select() { }
}

and the error has been changed! Now it's "Class "Checkbox" implements interface "SelectableControl" wrongly. Types have separated declarations of private property "state"." (again, translation to English). Q3. Why the error has changed?!.

The concept that an interface can inherit a class looks very unfamiliar to me, so I cannot understand all these nuances...

Upvotes: 0

Views: 33

Answers (1)

Dmitriy
Dmitriy

Reputation: 2822

TypeScript is a structurally typed language, so when you inherit an interface from class it is equivalent to just copy-pasting the field / method definitions from a class to that interface, i.e.:

// no extends, just copy-paste
interface SelectableControl { 
    public state: any;
    select(): void;
}

And you can see that in the output as well, that 2 classes end up not inheriting from each other:

https://www.typescriptlang.org/play/index.html?ssl=1&ssc=1&pln=38&pc=1#code/MYGwhgzhAEDCD2A7ALgJ3iaBvAsAKGkOgAcBXAIxAEthoJkxkBTALmjEQE8BufAX3z4qKJqgBmYYE2gBlJiCbAGlJghTpMTAB7NEAExhq0GbPiJ15i5AAoAlGwBu8Knt54BefKEiGAFooBrcngtaCoAW2IFcKYUGDkFJTAVIw1TAiIySho6BmY2Dh4zIghLJTtsaA8+IA

I believe this should answer all of the questions that you have, but if not I would be happy to expand.

Upvotes: 1

Related Questions