# 추가적인 타입 검사 satisfies 연산자

## satisfies

> **타입 추론을 그대로 활용하면서** **추가로 타입검사를 하고 싶을 때 사용**

* TS 4.9 버전에서 satisfies 연산자가 추가됨
* 만족하다는 의미, 특정 객체 타입 검사용 으로 사용
* 즉, 타입 선언이 아닌 추론된 타입에서 타입 검사를 하는 방법!!

```typescript
// sirius 대신 sriius로 오타낸 상황

const universe = {
  sun: "star",
  sriius: "star", // sirius 오타
  earth: { type: "planet", parent: "sun" },
}

// key: sun | sriius | earth
// value: {type: string, parent: string } | string
```

* 인덱스 시그니처를 사용해서 타이핑하면 sirius의 오타는 잡히게됨

```typescript
const universe: {
  [key in 'sun' | 'sirius' | 'earth']: { type: string, parent: string } | string 
  } = {
    sun: "star",
    sriius: "star", // sirius 오타 잡힘
    earth: { type: "planet", parent: "sun" },
  }
}
```

### 속성 값을 사용할 때가 문제가 발생함

* earth의 타입이 객체라는 것을 제데로 잡아내지 못한다.

```typescript
universe.earth.type; 
// Property 'type' does not exist on type 'string | {type: string; parent: string;}',
// Property 'type' does not exist on type 'string'
```

* 속성 값의 타입을 객체와 문자열의 유니언으로 표기했기 때문에 earth가 문자열일 수도 있다고 생각함
* 즉, earth 도 string | {type: string, parent: string} 타입으로 인식하게됨

### 추론의 이점을 누리면서 오타를 잡아내는 방법

> 객체 리터럴 뒤에 'satisfies' 를 표기하면 된다.

* 타입 추론된것을 그대로 사용하면서 각각의 속성들을 staisfies에 적은 타입으로 다시 한번 검사

```typescript
const universe = {
  sun: "star",
  sriius: "star", // sirius 오타
  earth: { type: "planet", parent: "sun" },
}

// 추론된 타입 (정확하게 추론된다.)
const universe: {
  sun: string;
  sriius: string;
  earth: {
    type: string;
    parent: string;
  }
}
// satisfies 사용
const universe = {
  sun: "star",
  sriius: "star", // sirius 오타
  earth: {type: "planet", parent: "sun"},
} satisfies {
  [key in 'sun' | 'sirius' | 'earth']: { type: string, parent: string } | string 
}
```

### Zerocho ver

* 변수에 값을 제공을 했음에도 타입이 옵셔널이라 오류가 발생한다.
* `: NamedCircle` 타입 선언을 지우면 객체의 유효성을 검사하지 못하므로 딜레마에 빠진다
* 이럴 때 사용할 수 있는 것이 `satisfies`

```typescript
type NamedCircle = {
  redius: number;
  name?: string;
}

const circle: NamedCircle = {radius: 1.0, name: 'woong'};

// circle.name은 optional type으로 undefined일 수 있기 때문에 오류 발생
console.log(circle.name.length);
```

```typescript
type NamedCircle = {
  redius: number;
  name?: string;
}
// radius가 NamedCircle을 위반하여 오류 발생
const wrongCircle = {radius: '1.0', name: 'woong'};
	satisfies NamedCircle;

/* 객체 리터럴이 NamedCircle 타입과 일치하도록 보장되며
* 추론된 타입은 name 필드가 옵셔널이 아닌 필드가 된다.
*/
const circle = {radius: 1.0, name: 'woong'};
	satisfies NamedCircle;

// circle.name은 undefined가 될 수 없다.
console.log(circle.name.length);
```


---

# 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://taewoongs-organization.gitbook.io/jtwjs-dev-wiki/dev_note/typescript/undefined/satisfies.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.
