[TypeScript] Type Challenges #2- Get Return Type

51 阅读1分钟

题目描述

不使用 ReturnType 实现 TypeScript 的 ReturnType<T> 泛型。

例如:

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

type a = MyReturnType<typeof fn> // 应推导出 "1 | 2"

题解

// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'

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>>>,
]

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


// ============= Your Code Here =============
type MyReturnType<T extends CallableFunction> = T extends (...args: any[]) => infer R ? R : never

使用T extends CallableFunction对传入的类型参数T进行约束,确保T是一个可调用的函数类型

通过T extends (...args: any[]) => infer R条件表达式来推断函数的返回值类型。其中,infer R从函数T中推断出返回值的类型,并存储在R

T是可调用函数时,返回推断出的返回值类型R,否则返回never