본문 바로가기

FE/type-challenge

2. ReturnType

728x90

문제

내장 제네릭 ReturnType<T>을 이를 사용하지 않고 구현하세요.

const fn = (v: boolean) => {
  if (v)
    return 1
  else
    return 2
}

type a = MyReturnType<typeof fn> // should be "1 | 2"

cases

type cases = [
  Expect<Equal<string, MyReturnType<() => string>>>,
  Expect<Equal<123, MyReturnType<() => 123>>>,
  Expect<Equal<ComplexObject, MyReturnType<() => ComplexObject>>>,
  Expect<Equal<Promise<boolean>, MyReturnType<() => Promise<boolean>>>>,
  Expect<Equal<() => 'foo', MyReturnType<() => () => 'foo'>>>,
  Expect<Equal<1 | 2, MyReturnType<typeof fn>>>,
  Expect<Equal<1 | 2, MyReturnType<typeof fn1>>>,
  Expect<Equal<1 | 2, MyReturnType<typeof fn2>>>,
]

type ComplexObject = {
  a: [12, 'foo']
  bar: 'hello'
  prev(): number
}

const fn = (v: boolean) => v ? 1 : 2
const fn1 = (v: boolean, w: any) => v ? 1 : 2
const fn2 = (v: boolean, w: any) => w ? 1 : 2

문제 링크

정답

type MyReturnType<T> = T extends (...arg: any[]) => infer U
  ? U
  : never

풀이

조건

  1. 함수타입의 반환값을 출력해라.

해설

우선, 일반적으로 T를 검사해 반환값을 가져오는 로직을 개발한다.

type MyReturnType<T> = T extends () => infer U
  ? U
  : never

많은 test case가 통과하지만, 마지막 세가지 요소는 통과하지 못한다.

이것은 return type이 복잡해서라기 보다, 함수 파라미터가 지정되지 않아서 extends를 만족하지 못하기 때문이다.

이 점을 수정하면 다음과 같다.

type MyReturnType<T> = T extends (...arg: any[]) => infer U
  ? U
  : never

혹시 오류나 개선점이 있다면 댓글 부탁드립니다

728x90

'FE > type-challenge' 카테고리의 다른 글

8. Readonly2  (0) 2023.09.01
3. Omit  (0) 2023.08.31
7544. ConstructTuple  (0) 2023.08.26
5360. Unique  (0) 2023.08.25
5821. MapTypes  (0) 2023.08.24