Interfaces (within Typescript) are used in a variety of ways.
Defining expectations/restrictions
We can define an interface such as IPoint
interface IPoint { x: number; y: number; }
Just like other languages, we can then implement this interface and we’re required to duplicate the properties or methods declared on it.
For example here’s an implementation
class Point implements IPoint { constructor(public x: number, public y: number) { } }
We’ve used public constructor parameters hence implementing the IPoint interface.
Now we can create an instance of the Point like this
// p is a Point var p = new Point(2, 3); // p is declared as an IPoint var p: IPoint = new Point(2, 3);
Within TypeScript an interface can also simply be thought of as shaping our data, so in this example we could create an anonymous class of type IPoint like this
var p: IPoint = {x : 2, y: 4};
We can also declare an instance of an anonymous type like this
var p = {x : 2, y: 4};
Typescript supports “duck typing” so we can create functions such as
function output(p: IPoint) { // }
and we can pass a type which implements an IPoint or a duck typed anonymous type, for example
output({x : 2, y: 4});
Because of duck typing we do have an issue whereby the following two interfaces are structurally equivalent
interface IPoint { x: number; y: number; } interface I2d { x: number; y: number; }
and hence this will compile and run
var i2d: I2d = {x : 2, y: 4}; var p: IPoint = i2d;
In such a case, the interfaces have the same properties and names and are structurally equivalent.
Things get a little more interesting with interfaces and anonymous types, in that we can write something like this
function whatIsThis() { return {x:2}; }
Obviously it’s not an IPoint or I2d, but it could be. In this example it’d create an anonymous type but we could cast the type like this, but this will fail to compile due to the missing y property.
function whatIsThis() { return <IPoint>{x:2}; }
Empty interfaces
We can also define empty interfaces, such as
interface IEmpty {} function output(e: IEmpty) { console.log(e); } output("Hello World");
In this case this is equivalent to an any and hence does not cause a compile time error and output will display “Hello World”.
Type erasure
Interfaces within Typescript are erased at compile/transpile time, hence whilst they aid in ensuring our types are as expected, once compiled to JavaScript they’re removed.
Hence no runtime type checking exists for such types.