前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

# 高级类型之强大的infer关键字

infer 是工具类型和底层库中非常常用的关键字,表示在 extends 条件语句中待推断的类型变量,相对而言也比较难理解,我们不妨从一个 typescript 面试题开始:

我们之前学过 ReturnType 用于获取函数的返回类型,那么你会如何设计一个 ReturnType?

interface User {
    id: number
    name: string
    form?: string
}

type Foo = () => User

type R1 = ReturnType<Foo> // User
@前端进阶之旅: 代码已经复制到剪贴板

# 条件类型与infer

我们先看一个简单例子:

type ParamType<T> = T extends (param: infer P) => any ? P : T;
@前端进阶之旅: 代码已经复制到剪贴板

上面例子表示,如果 T 能赋值给 (param: infer P) => any,则结果是(param: infer P) => any类型中的参数 P,否则返回为 T,infer P表示待推断的函数参数.

我们再回到开始的面试题,由于接受的函数返回类型是未知的,所以我们需要用infer P代表函数返回类型,如下:

type ReturnType<T> = T extends (...args: any[]) => infer P ? P : any;
@前端进阶之旅: 代码已经复制到剪贴板

其实TypeScript也内置了一个获取构造函数参数的工具类型:

  • ConstructorParameters<T> – 提取构造函数中参数类型
class TestClass {
    constructor(public name: string, public age: number) {}
}

type R2 = ConstructorParameters<typeof TestClass> // [string, number]
@前端进阶之旅: 代码已经复制到剪贴板

我们再试着把它实现一下:

type ConstructorParameters<T extends new (...args: any[]) => any> = T extends new (...args: infer P) => any
  ? P
  : never;
@前端进阶之旅: 代码已经复制到剪贴板

我们一步步分析一下这个工具类型:

  1. new (...args: any[]指构造函数,因为构造函数是可以被实例化的.
  2. infer P代表待推断的构造函数参数,如果接受的类型T是一个构造函数,那么返回构造函数的参数类型P,否则什么也不返回,即never类型

# infer的应用

infer非常强大,由于它的存在我们可以做出非常多的骚操作.

  1. tuple转union,比如[string, number] -> string | number:
fe
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏