# Extends

extends 는 typescript 에서 다양하게 사용이 가능합니다. 크게 아래와 같은 용도로 사용 됩니다.

* 확장
* 제한
* 조건부
* 추론 (with Infer)

## 타입의 확장

이름 그대로 interface 를 확장하고 싶을때 사용이 가능합니다. type 의 intersection(&) 문법과 동일한 기능입니다.

```typescript
type Profile = { name: string; age: number }
type DogProfile = Profile & { breed: 'Bulldog' | 'Poodle' };
// DogProfile { name: string; age:number; breed: 'Bulldog' | 'Poodle' }

interface DogProfile extends Profile {
    breed: 'Bulldog' | 'Poodle'
}
// DogProfile { name: string; age:number; breed: 'Bulldog' | 'Poodle' }

```

## Generic 의 타입 제한 하기

ts 함수의 인자 처럼 제너릭 타입을 제한 할수 있습니다.

```typescript
type MessageOf<T> = T["message"];
// Type Error: Type '"message"' cannot be used to index type 'T'.

type MessageOf<T extends { message: unknown }> = T["message"];

type Email = { message: string; }
type Chat = { text: string; }

type EmailMessage = MessageOf<Email>
type Email = MessageOf<Chat> // Type Error
```

위의 예시에서 첫번째 MessageOf 을 확인해 봅시다. 제너릭 T 의 타입은 정해지지 않았습니다. 따라서, property 에 message 가 없을 수 도 있기 때문에 에러가 발생 합니다.&#x20;

두번째 MessageOf 같은 경우는 extends 로 타입을 제한합니다. message property 를 가진 타입만 제너릭으로 들어올 수 있으므로, Error 가 발생하지 않습니다.&#x20;

반대로 제너릭을 사용할 때 옳지 않은 타입을 넘겨주면 Type Error 가 발생합니다.

{% embed url="<https://www.typescriptlang.org/ko/docs/handbook/2/generics.html#%EC%A0%9C%EB%84%A4%EB%A6%AD-%EC%A0%9C%EC%95%BD%EC%A1%B0%EA%B1%B4-generic-constraints>" %}

## 조건부 타입

extends 는 많은 언어가 포함하고 있는 if 의 역할을 하기도 합니다.

```typescript
type Example = "A" extends string ? "STRING" : "UNKNOWN"; // "STRING"

// 제너릭에서 사용이 가능합니다.
type MessageOf<T> = T extends { message: unknown } ? T["message"] : never;

interface Email { message: string; } 
interface Dog { bark(): void; }
 
type EmailMessageContents = MessageOf<Email>; // string
type DogMessageContents = MessageOf<Dog>; // never           


// 중첩도 가능 합니다.
type TypeOf<T> = T extends string
  ? 'string'
  : T extends number
  ? 'number'
  : T extends boolean
  ? 'boolean'
  : 'unknown'

type StrType = TypeOf<string> // "string"
type StrType = TypeOf<number> // "string"
type StrType = TypeOf<Function> // "unknown"

```

## 타입 추론 Infer

아래와 같은 타입이 있다고 가정해봅시다. 우리는 때로 'User' 타입이 필요할 수 있습니다. 그럴땐 infer 키워드를 통해 타입을 추론 할 수 있습니다.

```typescript
const userList = [{ name: 'John' }] // type: Array<User>

type ItemOf<T> = T extends Array<infer U> ? U : unknown;
type User = ItemOf<typeof userList>; // User { name: string }
```

위에서 infer U 는 추론하고자 하는 타입을 의미합니다. 위의 ItemOf 를 문맥 그대로 해석해 봅시다.

제너릭 T 가 Array<추론하고자 하는 타입> 타입의 형태를 하고 있다면 ItemOf 의 반환 타입은 추론하고자 하는 타입이고, 아니면 unknown 이 라고 해석할 수 있습니다.


---

# 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://toktokhan.gitbook.io/docs/onborading/growing-up/ts-skill/extends.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.
