[[Union]]인 변수가 존재할 때 하나의 타입으로 좁히고 싶을 때 `type predicates` 가 유용하다. ```typescript const values = ["a", "b", undefined, "c", undefined]; const filteredValues = values.filter((value) => Boolean(value)); ``` 위의 예제에서 `values`의 타입은 `(string | undefined)[]`인데 `filter`함수를 실행시키면 `filteredValues`의 타입은 `string[]`으로 예상하지만 실제로는 `(string | undefined)[]` 으로 추론이 되어버린다. ![[filtered value.png]] `string | undefined` [[Union]] 타입에서 하나의 타입(`string`)으로 추론시키기 위해서 아래와 같이 `filter` 에 넘겨주는 `predicate function` 리턴 타입을 `value is string`으로 지정하면 우리가 원하는 타입으로 추론이 된다. ```typescript const filteredValues = values.filter((value): value is string => Boolean(value)); ``` Type predicates 사용은 함수에서만 가능하다. 사용법은 함수 리턴 타입 지정하는 곳에 `(매개 변수) is (타입)` 형태로 코드를 작성하고 **반드시 함수에서 리턴하는 타입은 Boolean 이어야 한다.** 한가지 예를 더 살펴보면, ```typescript interface User { speak(): void } interface Dog { howl(): void } function isDog(creature: User | Dog): creature is Dog { return creature.howl !== undefined } const creature: User | Dog = {howl: () => {}} if (isDog(creature)) { creature.howl() // Dog로 타입 추론 } ``` `isDog` 함수에 [[Union]]타입을 넘겨주면 (유저 또는 개) `isDog` 함수 내부에서는 `howl` 함수가 존재하는지 확인한다. 앞서 말한 대로 반드시 boolean 타입을 리턴하면 `isDog` 실행 후 조건문 내부에선 `creature`가 `User`또는 `Dog`가 아닌 `Dog`로 추론이 된다. --- 참조 강의: https://inf.run/FVDi