Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why field declaration is must in class as it implements an interface

I want to clear my concept in implementation of an interface on a class.

An interface is something like a template which cannot make an impact until a class implements it. (link)

So if I define an interface as:

interface IVehicle {
    color: string,
    model_no: number,
}

And then I make a class as:

class Vehicle implements IVehicle {

}

It's giving me red underline at class name. Why I must declare the fields again in the class as it is implementing an interface it must not fetch its fields?

Why we must write like this?

class Vehicle implements IVehicle {
    color: string;
    model_no: number;
}

Then what is the concept of interfaces that a class can't fetch the fields of an interface whose it implements, what if I don't implement an interface and directly declare the fields in a class. I am thinking that why developers of TypeScript added this thing? It doubles up the code; first make an interface, declare fields in there, than make a class (also add implements InterfaceName), then again declare those fields in that class, why?


1 Answers

because this is also valid:

interface IVehicle {
    color: string;
    model_no: number;
}

class ClownCar implements IVehicle {
    // can be a subset of original type
    public color: 'red' | 'green' | 'blue';
    public model_no: 250 = 250;
}

class NonEditableCar implements IVehicle {
    // can use getter or setters instead, doesn't have to be normal field
    get color() {
        return 'grey';
    }
    get model_no(){
        return 100;
    }
}

An interface just says that an instance will have those fields, it doesn't say it must match that exact type. The declaration you have in the class specifies that the implementation is to store an instance variable which needs to be initialized.

You can narrow instance variables and widen method call signatures while still implementing an interface:

interface VehicleCarrier {
    contents: IVehicle[];
    launch(count: number): void;
}

class AircraftCarrier implements VehicleCarrier {
    // this is more specific, and because the inteface forces you to write it you have to consider that
    // it should be more specific.
    public contents: (Plane | Submarine)[];
    // can extend call signatures for methods
    public launch(count: number, type: 'plane' | 'sub' = 'plane') {}
}
like image 98
Tadhg McDonald-Jensen Avatar answered Jan 01 '26 09:01

Tadhg McDonald-Jensen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!