관리 메뉴

Jerry

[TIL] [타임어택9기][리뉴얼] 타입스크립트 올인원 : Part2. lib.es5.d.ts 분석- (12) : filter 제네릭 분석 본문

Front/Typescript

[TIL] [타임어택9기][리뉴얼] 타입스크립트 올인원 : Part2. lib.es5.d.ts 분석- (12) : filter 제네릭 분석

juicyjerry 2024. 3. 2. 16:55
반응형
filter 제네릭 분석

 

 

 

 

 

interface Array<T> {
    filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
    filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
}

const filtered = [1, 2, 3, 4, 5].filter((value) => value % 2); // (1)
const filtered = ['1', 2, '3', 4, '5'].filter((value) => typeof value === 'string'); // (2)

 

1번 코드는 number[]으로 추론 잘 됨

2번 코드는 string[]으로 추론 잘 안 됨 -> Why?

 

 

 

 

 

 

그 이유는 무엇일까?

interface Array<T> {
    filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; // (1)
    filter<S extends string | number>(predicate: (value: string | number, index: number, array: string | number[]) => value is S, thisArg?: any): string | number[]; // (2)
    filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
}

 

현재 interface Array<T> 에서 

1번에 들어가는 타입 추론을 직접 대입해보았을 때,

2번처럼 볼 수 있고 string | number[] 가 추론된다.

 

 

 

 

 

 

그렇다면, string[]으로 추론되는 결과를 보고 싶으면 어떻게 해야 할까?
filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; // (1) 
filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[]; // (2)

const predicate = (value: string | number): value is string => typeof value === 'string';
const filtered2 = ['1', 2, '3', 4, '5'].filter(predicate);

 

위 코드 예시를 비교해서 확인해보자.

1번은 S가 number 혹은 string이 될 여지가 있지만

2번은 T로 고정되어 있어서 가능성이 없다.

 

 

 

 

추천 공부 방법 : 타입스크립트에서 만든 자바스크립트에 대한 타입핑들(lib.es5.d.ts) 을 따라 해보면서 학습

 

반응형