Close

TypeScript - Using Interfaces to describe Object Properties

[Last Updated: Sep 7, 2018]

In object-oriented programming, Interfaces are used to represent abstract types.

JavaScript do not have interfaces. In TypeScript, interfaces are used for strong typing during compile time only.

In this tutorial, we will see one of the uses of interfaces in TypeScript.

In Typescript, an interface can be used to describe an Object's required properties along with their types.

Suppose we created an interface 'I' with properties x and y. Any arbitrary object's instance 'o' can be declared with type 'I' if 'o' has same properties x and y; this feature is known as "Duck Typing".

Basic Example

Let's define an interface with some properties.

interface Person {
    name: string;
    age: number;
}

Now create an ordinary JavaScript object with same properties.

let p = {name: "Ashlee", age: 29};

Here TypeScript allows us to declare the variable 'p' with type 'Person':

let p: Person = {name: "Ashlee", age: 29};

In above line variable 'p' has become statically typed . From this point on TypeScript's type system will warn us if we violate any typing rules on 'p'.

When interfaces are used to describe properties, we don't have to create a concrete implementation of them and also we don't have to create an instance of the interface by using new operator. They just describe an object as reusable type.

No interfaces during runtime

As interfaces are only compile time static typing aid, the compiled JavaScript does not have any equivalent construct for them.

Our last example:

interface Person {
    name: string;
    age: number;
}

let p: Person = {name: "Ashlee", age: 29};

is compiled to following JavaScript:

let p = {name: "Ashlee", age: 29};

Order does not matter

The properties in object literal and the properties in target interface not necessarily need to be in same order:

random-ordering.ts

interface Person {
    name: string;
    age: number;
}

let p: Person = {age: 29, name: "Ashlee"};

Function calls

An object literal can be successfully pass to a function if all properties match:

function-calling.ts

interface Person {
    name: string;
    age: number;
}

function displayPerson(person: Person): void {
    console.log(person);
}

displayPerson({age: 29, name: "Ashlee"});


Output

{ age: 29, name: 'Ashlee' }

Strict type checking for excess properties

We cannot include extra properties in the object:

strict-checking.ts

interface Person {
    name: string;
    age: number;
}

let peron: Person = {name: "Ashlee", age: 29, phone: "111-111-111"};
let date: Date = new Date();
let ar: Array<number> = [1, 3, 5];

Output

strict-checking.ts(6,47): error TS2322: Type '{ name: string; age: number; phone: string; }' is not assignable to type 'Person'.
Object literal may only specify known properties, and 'phone' does not exist in type 'Person'.

Lenient type checking when type is not specified

TypeScript does not do strict checking for excess properties when we don't specify the object type and then assign/pass it to the target type (only required properties should be there):

lenient-checking.ts

interface Person {
    name: string;
    age: number;
}

function displayPerson(person: Person): void {
    console.log(person);
}

let p = {name: "Ashlee", age: 29, phone: "111-111-111"};
//assigning to a target type
let p2: Person = p;
//passing to a function
displayPerson(p);

Output

{ name: 'Ashlee', age: 29, phone: '111-111-111' }

Excess properties checks for object literals

In the last example, if we pass an object literal with extra properties then that will be a compiler error:

literal-excess-property-checks.ts

interface Person {
    name: string;
    age: number;
}

function displayPerson(person: Person): void {
    console.log(person);
}

displayPerson({name: "Ashlee", age: 29, phone: "111-111-111"});

Output

literal-excess-property-checks.ts(10,41): error TS2345: Argument of type '{ name: string; age: number; phone: string; }' is not assignable to parameter of type 'Person'.
Object literal may only specify known properties, and 'phone' does not exist in type 'Person'.
Object literals get special treatment and undergo excess property checking.

The above error can be fixed by the use of type assertion:

pass-literal-with-type-assertion.ts

interface Person {
    name: string;
    age: number;
}

function displayPerson(person: Person): void {
    console.log(person);
}

displayPerson({name: "Ashlee", age: 29, phone: "111-111-111"} as Person);

Output

{ name: 'Ashlee', age: 29, phone: '111-111-111' }

Example Project

Dependencies and Technologies Used:

  • TypeScript 3.0.1
Interfaces describing properties examples Select All Download
  • typescript-interface-describing-object
    • basic.ts

    See Also