- 게시일
TypeScript Array filter 타입 좁히기
date
Nov 8, 2023
slug
typescript-array-filter-타입-좁히기
status
Published
tags
TypeScript
summary
타입 가드로 Array filter 타입 추론하기
type
Post
TypeScript에서 배열의 .filter()
메서드는 타입을 필터링하지 않는다.
TypeScript는 코드 구조와 주석을 기반으로 타입을 결정하는 정적 타입 시스템이다. 따라서 필터링 조건이 더 구체적인 서브타입을 제안하더라도 결과 배열의 타입을 자동으로 좁히지 않는다.
필터링된 배열의 타입을 명시적으로 좁히려면 타입 가드 함수를 사용해야 한다.
다음 예제를 확인해보자.
interface Bird { type: "bird"; flyingSpeed: number; } interface Fish { type: "fish"; swimmingSpeed: number; } type Animal = Bird | Fish; const animals: Animal[] = [ { type: "bird", flyingSpeed: 10 }, { type: "fish", swimmingSpeed: 15 }, ]; const isBirdWithoutTypePredicate = (animal: Animal) => animal.type === "bird"; const isBird = (animal: Animal): animal is Bird => animal.type === "bird"; const birds1 = animals.filter(isBirdWithoutTypePredicate); const birds2 = animals.filter(isBird); const birds3 = animals.filter((animal) => isBird(animal));
TS Playground
birds1
의 경우 타입 가드 함수를 사용하지 않아Bird[]
가 아닌Animal[]
로 추론되는 것을 확인할 수 있다.
birds2
의 경우 타입 가드 함수를 사용하여Bird[]
로 추론되는 것을 확인할 수 있다.
birds3
의 경우 화살표 함수 내에서 타입 가드 함수를 사용하지만, 화살표 함수 자체는 타입 가드 함수가 아니므로Animal[]
로 추론되는 것을 확인할 수 있다.
.filter(Boolean)
의 경우
이 글을 작성하게 된 계기이다. 자바스크립트에서 배열에 있는 nullish한 값을 필터링하기 위해
.filter(Boolean)
를 자주 사용했는데, 타입스크립트에서 위에서 말했던 타입 문제로 인해 당황한 경험이 있다.다음과 같이 유틸리티 타입인
NonNullable
을 사용하여 타입 가드 함수를 작성하면 문제 없이 타입을 좁힐 수 있다.const array = ["item1", "item2", null, undefined]; const isNonNullable = <T extends unknown>(v: T): v is NonNullable<T> => Boolean(v); const filteredArray = array.filter(isNonNullable);