# Type vs Interface

## 학습 키워드

* 타입별칭(Type)
* 인터페이스(interface)
* 타입별칭(Type) vs 인터페이스(interface)

<br>

## 타입별칭

* 변수를 선언하듯 타입을 별도로 정의할 수 있다.
* `type 타입이름 = 타입` 타입의 이름은 대문자로 지정

```typescript
type TGender = 'female' | 'male';
type TUser = {
  name: string;
  age: number;
  gender: TGender; // 👈🏻 type별칭 안에 또다른 type별칭으로 적용이 가능하다.
};

const user1: TUser = {
  name: '홍길동',
  age: 20,
};
```

> 🚨 동일한 스코프 내에서는 동일한 이름의 타입별칭을 선언하는것은 불가능하다!

```typescript
type TUser = {
  name: string;
  age: number;
};

type TUser = {
  // ❎ 동일한 이름이 타입 지정은 안된다.
};
```

```typescript
type TUser = {
  name: string;
  age: number;
};

function Test() {
  type TUser = {
    // ✅ 스코프가 다르면 동일한 이름 사용 가능
    name: string;
    address: string;
  };

  const user: TUser = {
    name: '홍길동',
    address: '서울특별시',
  };
}
```

> 🚨 타입을 리터럴로 지정해둔다면?

```typescript
type TGender = 'female' | 'male';
type TUserPick = {
  name: string;
  age: number;
  gender?: TGender; // 👈🏻  타입을 'female' | 'male' 라고 리터럴 방식으로 지정
};

const user1 = {
  name: '이나영',
  age: 30,
  gender: 'female', // 👈🏻 타입추론에 의해 타입은 string 지정
};

const user2: TUserPick = user1; // 🚨 gender의 타입이 맞지 않아, error
```

### 타입별칭의 확장

* `&` 연산자를 이용한 확장

```typescript
type Person = {
  name: string;
  age: number;
};

type MyWorker = Person & {
  // & 연산자를 통해 타입 확장
  company: string;
  readonly position: string; // 해당 키워드가 붙게되면 값을 읽어오는건 되지만, 변경하는건 할 수 없다.
  getMoney: (amount: number) => number;
};

type Employ = Person & MyWorker; // 새로운 타입을 생성해서 & 연산자를 사용한 확장법
```

> ✅ 읽기전용 readonly : 해당 키워드가 붙이면 값을 읽는건, 객체의 value 값 변경하는건 할 수 없다.

```typescript
interface Person {
  readonly name: string;
  age?: number;
}

const person: Person = {
  name: '김철수',
  // age: 27,
};

person.name = '홍길동'; // ❌
```

<br>

## 인터페이스

* 타입 별칭과 동일하게 타입에 이름을 지어주는 또 다른 문법
* 원시타입은 지정할 수 없고, `객체` 타입만 지정 가능
* `interface 타입이름 {}` 타입의 이름은 대문자로 지정

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

> ⭐️ 동일한 스코프 내에서는 동일한 이름의 인터페이스 선언이 가능하다!

```typescript
interface IBox {
  width: number;
  height: number;
}

interface IBox {
  shape: string;
}

const boxModel2: IBox = {
  width: 20,
  height: 30,
  shape: '네모',
};
```

### 인터페이스의 확장

* `&` 연산자를 활용한 확장

```typescript
interface IPerson {
  name: string;
  age: number;
}

interface IWorker {
  company: string;
  readonly position: string;
  getMoney: (amount: number) => number;
}

const employee: IWorker & IPerson = {
  name: '이나영',
  age: 30,
  company: 'google',
  position: 'teacher',
  getMoney: (amount: number) => {
    return amount;
  },
};
```

* `extends`를 사용한 확장

```typescript
interface IUser {
  name: string;
  age: number;
}

interface IUserAddress extends IUser {
  code: string;
  address: string;
}

const userAddress: IUserAddress = {
  name: '김철수',
  age: 20,
  code: '13456',
  address: '서울특별시 강남구',
};
```

### 다중확장

* `,`를 사용한 확장

```typescript
interface IUser {
  name: string;
  age: number;
}

interface IWorker {
  company: string;
  readonly position: string;
  getMoney: (amount: number) => number;
}

interface IUserAddress extends IUser, IWorker {
  // 타입을 확장할 때 extends를 통해 확장한다. ( , 를 통해 확장 가능 )
  code: string;
  address: string;
}

const userAddress: IUserAddress = {
  name: '김철수',
  age: 20,
  code: '13456',
  address: '서울특별시 강남구',
  company: 'google',
  position: 'teacher',
  getMoney: (amount: number) => {
    return amount;
  },
};
```

<br>

### 타입별칭(Type) vs 인터페이스(interface)

* 선언방식의 차이
* 확장방식의 차이

> 🤥 개발자의 취향에 따라 사용하는 방식이 다를뿐 두가지의 큰 차이는 없다.

<br>

## 🔗 참고

* [한입크기로 잘라먹는 타입스크립트](https://ts.winterlood.com/c3003661-2e05-4044-a637-a4c5f1284919)
* [캡틴판교 타입스크립트 핸드북](https://joshua1988.github.io/ts/guide/basic-types.html#any)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://magrowing.gitbook.io/magrowing-gitbook/project/project_camp/typescript/type_interface.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
