> For the complete documentation index, see [llms.txt](https://taewoongs-organization.gitbook.io/jtwjs-dev-wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://taewoongs-organization.gitbook.io/jtwjs-dev-wiki/dev_note/typescript/undefined/satisfies.md).

# 추가적인 타입 검사 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);
```
