[Typescript] Interface


#Interface
オブジェクトの構造を表したものです。
Interfaceはオブジェクトのみ、Type aliasは全部いけます。

```interface.ts
interface Human {
  name: string;
  age: number;
}

const human: Human = {
  name: 'Quill',
  age: 38
}
```

#Interfaceにメソッドを追加する

方法１
↓関数を型注釈する方法

```interface.ts
interface Human {
  name: string;
  age: number;
  greeting: (message: string) => void;
}
```

↓方法２

```interface.ts
interface Human {
  name: string;
  age: number;
  greeting(message: string): void;
}
```

#classにInterfaceの条件を適用させる
implements　＝　実装

↓で、Humanの条件を満たすようなDeveloperを作るといったような解釈になります。

```interface.ts
interface Human {
  name: string;
  age: number;
  greeting(message: string): void;
}

class Developer implements Human{
}
```

↓また、implementsは複数付けることができます。

```interface.ts
class Developer implements Human, Job, Hobby{
}
```

#構造的部分型
↓最後の行では、Humanの{name, age, greeting}が入っていさえすればOKになります。
↓なのでnew Developerの引数にexperienceの値が入っていても問題ありません。

```interface.ts
interface Human {
  name: string;
  age: number;
  greeting(message: string): void;
}

class Developer implements Human{
  constructor(public name: string, public age: number, public experience: number) {}
  greeting(message: string) {
    console.log('Hello');
  }
}

const user: Human = new Developer('Quill', 38, 3);
```

↓わかりやすいようにtmpDeveloperを定義して書いてみても、これもOKです。

```interface.ts
interface Human {
  name: string;
  age: number;
  greeting(message: string): void;
}

class Developer implements Human{
  constructor(public name: string, public age: number, public experience: number) {}
  greeting(message: string) {
    console.log(message);
  }
}

const tmpDeveloper = {
  name: 'Quill',
  age: 38,
  experience: 3,
  greeting(message: string) {
    console.log(message);
  }
}
const user: Human = tmpDeveloper;
```

これらの何が良いかというと、パッとみただけで、
userは「少なくともHumanの中身の要素は持っているんだ」と分かることです。

#interfaceにreadonly修飾子を付ける
↓classと同じように付けることができます。
↓interfaceのnameにreadonlyを付けても、implementsのnameには影響を及ぼしません。

```interface.ts
interface Human {
  readonly name: string;
  age: number;
  greeting(message: string): void;
}

class Developer implements Human{
  constructor(public name: string, public age: number, public experience: number) {}
  greeting(message: string) {
    console.log(message);
  }
}
```

#interfaceを継承する
classと同じようにextendsを使います。

↓interface Humanにinterface Nameableを継承しています。

```interface.ts
interface Nameable {
  name: string;
}

interface Human extends Nameable {
  name: string;
  age: number;
  greeting(message: string): void;
}

class Developer implements Human{
  constructor(public name: string, public age: number, public experience: number) {}
  greeting(message: string) {
    console.log(message);
  }
}
```

interface Nameableのnameの型に、interface Humanの型が代入できる限り、
Humanの方の型は何度でも代入できます。

#interfaceで関数の型を表現する

↓メソッド名を書きません。
↓addFuncは、関数の型を定義したことと同じになります。
↓addFuncは、引数としてnumberを２つ持って、numberを戻り値として返します。

```interface.ts
interface addFunc {
  (num1: number, num2: number): number;
}
```

#？を使ってあってもなくても良い処理を実装する

？は、プロパティの前に付けることができます。

↓nickNameは、あってもなくてもエラーになりません。

```interface.ts
type Nameable = {
  name: string;
  nickName?: string;
}

const nameable: Nameable = {
  name: 'Quill'
}
```

↓パラメーターにも付けることができます。

```interface.ts
  greeting(message?: string) {
    console.log(message);
  }
```

↓fieldにも付けることができます。

```interface.ts
name?: string;
```