# TypeScript Unlocked: Interfaces

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">This article is a part of <a target="_blank" rel="noopener noreferrer nofollow" href="https://blog.troncodes.com/series/typescript-unlocked" style="pointer-events: none">TypeScript Unlocked</a> Series on my blog. Every article in the series is short, crisp and filled with examples and code snippets. If you want to learn TypeScript from scratch for absolutely FREE!!! check it out.</div>
</div>

Interfaces works similar to type keyword which we have discussed earlier in the series. Interface allows us to define the structure of the object just like **type** but there are few differences.

```typescript
interface User {
    readonly id : number // setting this as readonly field
    name: string 
    age?: number // setting this as optional field
    isLoggedIn(): string // method named isLoggedIn which returns string
    getStatus: () => string // similar methods can also be defined using this syntax
    getName(id:number) : string
}
 
const user: User = {
    id: 1234321,
    name: "Palash",
    isLoggedIn: ()=>{
        return "YES"
    },
    getStatus: ()=>{
        return "Online"
    },
    getName:(id:2)=>{
        return "usr" + id
    }
}
```

## Reopening of Interface

Sometimes we may want to add some additional properties to our interfaces after they has been defined. For example, if you have imported some **library** and it has some interfaces which you want to update. You can use the following syntax but this changes the original interface as well so if you are using the original interface in the future you have to add the new property which you have added.

```typescript
interface User {
    readonly id : number // setting this as readonly field
    name: string 
    age?: number // setting this as optional field
    isLoggedIn(): string // method named isLoggedIn which returns string
    getStatus: () => string // similar methods can also be defined using this syntax
    getName(id:number) : string
}

interface User { // reopening the Interface 
    phone: number
}
 
const user: User = {
    id: 1234321,
    name: "Palash",
    phone: 9898767852,
    isLoggedIn: ()=>{
        return "YES"
    },
    getStatus: ()=>{
        return "Online"
    },
    getName:(id:2)=>{
        return "usr" + id
    }
}
```

## Inheritance

we just saw how you can reopen an interface and add new properties but the drawback was it changes the original interface as well. So, if you want to update your interface but don't want to change the original one, we can use **Inheritance. Inheritance** establishes a relation between the parent interface and the child interface and both the interfaces are two separate interfaces. The child interface will have all the properties of the parent interface. One thing to note here is that unlike classes overriding methods of interfaces does not work.

```typescript
interface User {
    readonly id : number // setting this as readonly field
    name: string 
    age?: number // setting this as optional field
    isLoggedIn(): string // method named isLoggedIn which returns string
    getStatus: () => string // similar methods can also be defined using this syntax
    getName(id:number) : string
}

interface Admin extends User { // extending the Admin interface from user
    role: string
}

const admin: Admin = {
    id: 1234321,
    name: "Palash",
    role: "Admin",
    isLoggedIn: ()=>{
        return "YES"
    },
    getStatus: ()=>{
        return "Online"
    },
    getName:(id:2)=>{
        return "usr" + id
    }
}

}
```

## Interface `implements`

In TypeScript, the `implements` keyword is used to enforce that a class must conform to a particular interface or multiple interfaces. When a class implements an interface, it means the class must contain all the members (properties and methods) defined in that interface.

```typescript
interface MyInterface {
    // Properties or methods defined in the interface
}

class MyClass implements MyInterface {
    // Implementation of the properties or methods defined in the interface
}
```

```typescript
interface Printable {
    print(): void;
}

class Document implements Printable {
    print() {
        console.log('Printing document...'); // Implementing the 'print()' method from the 'Printable' interface
    }
}

const document = new Document();
document.print(); // Outputs: Printing document...
```

**Syntax for Implementing Multiple Interfaces:**

```typescript
interface Interface1 {
    method1(): void;
}

interface Interface2 {
    method2(): void;
}

class MyClass implements Interface1, Interface2 {
    method1() {
        // Implementation for method1
    }

    method2() {
        // Implementation for method2
    }
}
```

## Difference between type Aliases and Interface

Almost all features of an interface are available in type, the key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.

**TYPE**

Extending a type via intersections

```typescript
type Animal = {
  name: string;
}

type Bear = Animal & { 
  honey: boolean;
}

const bear = getBear();
bear.name;
bear.honey;
```

A type cannot be changed after being created

```typescript
type Window = {
  title: string;
}

type Window = {
  ts: TypeScriptAPI;
}

 // Error: Duplicate identifier 'Window'.
```

**INTERFACE**

Extending an interface

```typescript
interface Animal {
  name: string;
}

interface Bear extends Animal {
  honey: boolean;
}

const bear = getBear();
bear.name;
bear.honey;
```

Adding new fields to an existing interface

```typescript
interface Window {
  title: string;
}

interface Window {
  ts: TypeScriptAPI;
}

const src = 'const a = "Hello World"';
window.ts.transpileModule(src, {});
```
