I mean if you check out TS' documentation, parameters can be of type Interface. An interface can inherit from a class. Similarly a class can inherit from an interface.
An interface is a exactly what it sounds like. It's a description of a particular protocol for communication. Since objects communicate by calling methods on each other, this translates to descriptions of method signatures for an object, everything that the calling code needs to know to use it properly.
An interface A can 'extend' another interface B. This means that A includes all method signatures in B and then declares some more in addition to those.
A class is a description of an actual object. It provides the functionality that is desired. It actually defines what the methods do, i.e, provides the logic for the function, the body. When a class provides all the methods that an interface specifies, that class is said to "implement" the interface (not inherit from). I don't think it's possible in TypeScript for a class to "extend" an interface, only "implement".
In TypeScript when an interface A "extends" class B, it's really just saying that A extends the interface of class B, i.e, includes the signatures of all methods in B. This does NOT mean that the interface
I think it is only syntactic sugar, when you generate the ES5 code from a TS class that implements an interface, the code is exactly the same as if you don't implement that interface.
In the same way due to ES5 does not use types, when you declare an object as an interface in TS it will generate just an object. In TS you can do this because when you create the interface, TS knows which methods your objects will use.
The interface is a signature. It is a contract that implementations agree to adhere to. Using an interface, you have guarantees that certain properties or functions exist regardless of how the object is actually implemented.
The class is an implementation. Unlike an interface, a class can be instantiated. It contains the behaviors of that class, as well as the implementations of any interface it extends. Classes can also participate in inheritance. For example, in my 6502 chipset emulator written in TypeScript (github.com/JeremyLikness/redux6502) the interface IOpCode is a contract that op-codes can implement:
export interface IOpCode {
name: string;
value: OpCodeValue;
mode: AddressingModes;
size: Byte;
execute: (cpu: ICpu) => void;
}
The base class is default behavior shared by all op codes (a partial implementation):
export class BaseOpCode implements IOpCode {
private _execute: (cpu: ICpu) => void = cpu => {
throw new Error('Not implemented!');
}
constructor(
public name: string,
public value: OpCodeValue,
public mode: AddressingModes,
public size: Byte,
logic: (cpu: ICpu) => void) {
this._execute = logic;
}
public execute(cpu: ICpu): void {
this._execute(cpu);
}
}
And then each op code can inherit and override behavior explicit to that operation:
export class InvalidOpCode extends BaseOpCode {
constructor(public value: OpCodeValue) {
super(INVALID, value, AddressingModes.Single, 0x01, cpu => { });
}
}
The interface makes it possible for me to test higher order functions with my own stub or mock object to take the place of a "real" op code. The tests can interact using the interface without concern for how the implementation happens.
Interface: signature. "It should look like this and implement these things." Class: implementation. "It is an instance that does these things."
Hope that helps!
Ozzie Neher
Full Stack Dev
Haven't used TypeScript but generally in programming an interface is like a blueprint for a class. It defines things like what methods it needs to implement. It is a guarentee that the extending class will implement those methods.