해결된 질문
작성
·
571
1
//1번 filter인터페이스
filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
//2번 filter인터페이스
filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
//1번 예제
const filtered1 = ['1',2].filter((value)=>typeof value === 'string');
//2번 예제
const filtered2 = ['1',2].filter<string>((value)=>typeof value === 'string');
//3번 예제 (2번 예제 개선)
const filtered3 = ['1',2].filter<string>((value): value is string => typeof value === 'string');
위 코드를 기반으로, 궁금한 점이 있었습니다.
[질문1]
1번, 2번 예제코드 모두 똑같이 filter의 콜백함수의 반환 타입을 value is string 으로 명시하지 않았는데, 2번은 오류가 발생하고 1번은 오류가 발생하지 않는지?
[질문2]
왜 2번 예제처럼 제네릭 타입을 명시해줬을 때, filter의 콜백함수의 반환 타입을 value is string으로 따로 명시해줘야하는지?
그리고 이유를 생각해봤습니다. 제가 생각한 이유가 정확한지 모르겠어서 질문드립니다.
[질문1에 대한 생각]
1번 예제는 타입추론 시 2번 인터페이스를 따르기 때문에 filter 콜백의 반환 타입을 명시하지 않아도 오류가 뜨지 않는 것으로 생각했습니다. (타입 추론은 정확히 되지 않지만)
[질문2에 대한 생각]
2번 예제는 <string>으로 제네릭을 선언한 순간 1번 filter인터페이스를 따라야 합니다. 이때 filter의 콜백함수의 반환 타입을 value is string으로 명시하지 않으면 반환 타입이 boolean으로 추론되고, 이는 인터페이스와 맞지 않기 때문에 오류가 발생하는 것으로 이해했습니다. 따라서 3번 예제처럼 반환 타입을 타입 가드로 지정해 줬을 때는 오류가 뜨지 않았습니다. 수업내용 처럼 predicate를 따로 빼서 정의해서 사용하지 않아도 3번 예제처럼 작성해도 문제는 없는 걸까요?