从小而美的 Mitt 源码-学到的知识

950 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

Mitt 学习源码准备 前言

Vue3通信 推荐使用一个小巧的库: github.com/developit/m… 119行 | 总体积也就 ~200bytes 方便实用.

既然这么 "简单", 就有点感兴趣其源码是什么样子的, 瞅瞅源码, (Mitt 源码学习)

PS: 小巧只是代码行数相对较少(可一点不简单哟~),

关键学习其设计思想(关键!关键!关键!)(我怎么没脑回路呢?!)

Mitt仓库 GitHub Repo stars

mitt 源码仓库: github.com/developit/m…

Tiny 200b functional event emitter / pubsub.

主要源码就在 根目录下 src/index.ts 文件, 抛出这个函数 mitt(...){...}, 提出来简写如下, 下面开始详细学习:

// https://github.com/developit/mitt/src/index.ts
/**
 * Mitt: Tiny (~200b) functional event emitter / pubsub.
 * @name mitt
 * @returns {Mitt}
 */
export default function mitt<Events extends Record<EventType, unknown>>(
	all?: EventHandlerMap<Events>
): Emitter<Events> {
  // ...
  return {
    all,
    on(type, handler) {
      // ...
    },
    off(type, handler) {
      // ...
    },
    emit(type, handler) {
      // ...
    }
  }

2. Mitt 源码学习 前置知识点 查学准备: TypeScript

2.1 keyof

type Point = { x: number; y: string }
type P = keyof Point
type UnionType = Point[P] // number | string

2.2 union type

type UnionType = string[] | number[]
const list1: UnionType = [1, 2, 3] // OK
const list2: UnionType = ['1', '2', '3'] // OK
const list3: UnionType = ['1', 2, 3] // ERROR
// TS2322: Type '(string | number)[]' is not assignable to type 'UnionType'.
//   Type '(string | number)[]' is not assignable to type 'string[]'.
//     Type 'string | number' is not assignable to type 'string'.
//       Type 'number' is not assignable to type 'string'.
type UnionType2 = (string | number)[]
const list4: UnionType2 = ['1', 2, 3] // OK

2.3 Record 工具函数

Record 会经常用到: 将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型. 比较难理解吗? 上代码:

先看下源码:

/**
 * Construct a type with a set of properties K of type T 
 */ 
type Record<K extends keyof any, T> = { [P in K]: T; };

栗子: // 常用格式: 会将 K中的所有属性值都转换为T类型,并将返回的新类型返回给proxyKType

type proxyKType = Record<K,T>
type fruitsGroup = 'apple' | 'pear' | 'orange';
interface IFruitInfo {
    color: string,
    ind: number,
}

type IFruits = Record<fruitsGroup, IFruitInfo>;

const fruitsInfo:IFruits = {
    apple:{
        color:'appleColor',
        ind:1
    },
    pear:{
        color:'pearColor',
        ind:2
    },
    orange:{
        color:'arangeColor',
        ind:5
    }
}

2.4 utility-types

深入 ts 必备 工具类型

2.5 generics

class Person<T, K> {
  private name: T
  private age: K
  constructor(name: T, age: K) {
    this.name = name
    this.age = age
  }
}
const person1 = new Person<string, string>('person1', 4) // ERROR
const person2 = new Person<string, number>('person1', 4) // OK

下文预告: 学习源码不在怕!!

将具体学习 Mitt 源码, 因为行数不多 119行, 可逐行进行解读!!. 学习源码不在怕!!