Typescriptのinterface @yukilulu0229

https://typescriptbook.jp/reference/object-oriented/interface

## intaerface

タイプエイリアスを使うときにオブジェクトのみで使用できるもの

### 書き方

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

const human: Human = {
  name: "yukilulu",
  age: 20
}
console.log(human);

```

#### typeエイリアス

```interface.ts
type Hunman = {
  name: "yukilulu"
  age: 20
} | string

```

オブジェクト以外も指定できる

## メソッドの省略記法

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

const human: Human = {
  name: "yukilulu",
  age: 20,
  greeting(message: string) {
    console.log(message)
  }
}
console.log(human);

```

```
greeting: (message: string) => void
```
省略前

```
greeting(message: string) :void
```

省略後

こちらのほうが関数っぽくかける気がする


## implementsを使用してクラスにinterfaceをあてる

https://typescriptbook.jp/reference/object-oriented/interface/implementing-interfaces

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

class Developer implements Human {
  constructor(public name: string, public age: number, readonly country: string) {}
  greeting(message: string) {
    console.log(`hello ${message}`)
  }
}

console.log(Developer)

```
 implements は複数継承することができる


```
class Developer implements Human
```
このように当てる

```
constructor(public name: string, public age: number, readonly country: string) {}
```
constructorの中身はpublicかreadonlyのみ使用できる


## 構造的部分型

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

const human: Human = {
  name: "yukilulu",
  age: 20,
  greeting(message: string) {
    console.log(message)
  }
}
console.log(human);

class Developer implements Human {
  constructor(public name: string, public age: number, readonly country: string) {}
  greeting(message: string) {
    console.log(`hello ${message}`)
  }
}
console.log(Developer)

const user: Human = new Developer("snow", 20, "JP");
console.log(user);

```

```
interface Human {
  name: string,
  age: number,
  // greeting: (message: string) => void
  greeting(message: string) :void
}
```

```
constructor(public name: string, public age: number, readonly country: string) {}
```

```
const user: Human = new Developer("snow", 20, "JP");
```

userのHumanにはcountryが含まれてないがエラーにならない
これはHumanまでが型推論となるため

## readonlyで初期化以降の変更ができないようにする

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

class Developer implements Human {
  constructor(public name: string, public age: number, readonly country: string) {}
  greeting(message: string) {
    console.log(`hello ${message}`)
  }
}

let user: Human = new Developer("snow", 20, "JP");
console.log(user);
user.name = "change" // これができない

```

readonlyを使用することで初期化以降の変更ができないようにする

```
interface Human {
  readonly name: string,
  age: number,
  // greeting: (message: string) => void
  greeting(message: string) :void
}
```

readonlyをつける

```
user.name = "change" // これができない
```
readonlyなので変更ができなくなる

## extendsを使って継承

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

interface Human extends Nameable{
  age: number,
  // greeting: (message: string) => void
  greeting(message: string) :void
}
```

```
interface Human extends Nameable{
```

これによってNameableの内容が継承される

## interfaceで関数の型を作る

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

const addFunc: addFunc = (num1: number, num2: number) => {
  return num1 + num2
}

console.log(addFunc(10, 30))
```

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

```{}```の中に関数名が必要ない

基本的にはオブジェクトなのでこちらの書き方はしないほうがいい


## ?を使ったあってもなくてもよいプロパティを定義する

メソッドにもつけることができるので注意

```interface.ts
interface Nameable {
  name: string,
  nickName?: string
}

const nameable: Nameable = {
  name: "sunny"
}
```

```
nickName?: string
```
あってもなくてもよいを```?```で定義している

```
const nameable: Nameable = {
  name: "sunny"
}
```
nickNameがなくてもエラーにならない