새로운 타입 매개변수를 myFilter<S extends T>로 선언하겠습니다. S extends T인 이유는, 새로운 타입 매개변수는 배열 요소의 타입에 대입할 수 있어야 하기 때문입니다. map과 다르게 S는 T와 완전히 다른 타입일 수 없습니다. filter 메서드는 기존 요소에서 값을 추리는 것이므로 기존 타입을 벗어날 수 없는 것이죠.
하지만 이렇게 타입 매개변수 S를 도입해도 달라지는 부분이 없습니다. 타입스크립트가 콜백 함수의 반환값과 filter 메서드의 반환값 사이의 관계를 이해하지 못하기 때문입니다. 타입스크립트가 스스로 추론하지 못한다면 직접 입력하는 수밖에 없습니다. 다만 as로 강제로 주장하는 것은 아닙니다.
filter 메서드는 잘 보면 변수 r2나 r3에서 타입 좁히기를 수행하고 있습니다. number[]에서 never[]로, (string | number)[]에서 string[]으로 타입이 좁아졌습니다. 2.23절에서 직접 타입 좁히기를 수행할 수 있는 타입 서술 함수를 배운 것을 기억하나요? filter 메서드의 콜백 함수가 타입 서술 함수의 역할을 하면 됩니다.