TypeScipt 每日类型挑战-medium-<MyReturnType>

247 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

题目

获取函数返回类型 

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

例如:

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

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

解答

主要还是利用infer关键字类型推导的作用。它会在类型未推导时进行占位,等到真正推导成功后,它能准确地返回正确的类型。在TypeScript类型体操中的关键字详解(三)中我们提到extends关键字在TypeScript的高级类型操作中出现频率较高,主要使用场景有:接口继承 类型约束以及条件类型,这里使用的是其作为条件类型的情况,通常与infer关键字一起使用。

type MyReturnType<T> =  T extends (...args: any) => infer R ? R : T

代码详解:

  • T extends (...args: any) => infer R:判断T类型是否是一个函数的子类型,即T是不是一个函数。
  • infer R:表示待推导的函数返回类型为R,后续可以在表达式中使用R来代替真正的返回类型。

infer关键字总结

  1. 作用:类型推导,在类型未推导时进行占位,等到真正推导成功后,它能准确地返回正确的类型

  2. 注意点:

  • infer只能在 extends 条件语句中使用,声明变量只能在true分支中使用
  • 对使用了函数重载的函数进行类型推断时,以最后一个签名为准,因为一般这个签名是用来处理所有情况的签名。
  • infer在协变的位置上时,同一类型变量的多个候选类型将会被推断为联合类型;当infer在逆变的位置上时,同一类型变量的多个候选类型将会被推断为交叉类型。

更多

TypeScript类型体操中的关键字详解(一)

TypeScript类型体操中的关键字详解(二)

TypeScript类型体操中的关键字详解(三)

理清 TypeScript 的 interface 与 type 的区别