前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • 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
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

# 高级类型之索引类型、映射类型

我们从本节开始进入TypeScript学习的进阶阶段,因为我们要大量接触类型编程了。

本节我们将会学习比较抽象的索引类型,这个高级类型虽然相对要难理解一些,但是配合上类型操作符可以做出很多有趣的事情。

# 索引类型

我们先看一个场景,现在我们需要一个 pick 函数,这个函数可以从对象上取出指定的属性,是的,就是类似于 lodash.pick 的方法。

在 JavaScript 中这个函数应该是这样的:

function pick(o, names) {
  return names.map(n => o[n]);
}
@前端进阶之旅: 代码已经复制到剪贴板

如果我们从一个 user 对象中取出 id ,那么应该这样:

const user = {
    username: 'Jessica Lee',
    id: 460000201904141743,
    token: '460000201904141743',
    avatar: 'http://dummyimage.com/200x200',
    role: 'vip'
}
const res = pick(user, ['id'])

console.log(res) // [ '460000201904141743' ]
@前端进阶之旅: 代码已经复制到剪贴板

那么好了,我们应该如何在 TypeScript 中实现上述函数?结合我们之前学到的知识,你会怎么做?

如何描述 pick 函数的第一个参数 o 呢?你可能会想到之前提到过的可索引类型,这个对象的 key 都是 string 而对应的值可能是任意类型,那么可以这样表示:

interface Obj {
    [key: string]: any
}
@前端进阶之旅: 代码已经复制到剪贴板

而第二个参数 names 很明显是个字符串数组,这个函数其实很容易就用 TypeScript 写出来了:

function pick(o: Obj, names: string[]) {
    return names.map(n => o[n]);
}
@前端进阶之旅: 代码已经复制到剪贴板

这样似乎没什么问题,但是如果你够细心的话,还是会发现我们的类型定义不够严谨:

  • 参数 names 的成员应该是参数 o 的属性,因此不应该是 string 这种宽泛的定义,应该更加准确
  • 我们 pick 函数的返回值类型为 any[],其实可以更加精准,pick 的返回值类型应该是所取的属性值类型的联合类型

我们应该如何更精准的定义类型呢?

这里我们必须了解两个类型操作符:索引类型查询操作符和索引访问操作符。

# 索引类型查询操作符

keyof,即索引类型查询操作符,我们可以用 keyof 作用于泛型 T 上来获取泛型 T 上的所有 public 属性名构成联合类型。

举个例子,有一个 Images 类,包含 src 和 alt 两个 public 属性,我们用 keyof 取属性名:

class Images {
    public src: string = 'https://www.google.com.hk/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png'
    public alt: string = '谷歌'
    public width: number = 500
}

type propsNames = keyof Images
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专栏

  • 其他专栏