mitt源码 ts解析

201 阅读4分钟

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

一、ts内容

export type EventType = string | symbol;

// An event handler can take an optional event argument
// and should not return a value

export type Handler<T = unknown> = (event: T) => void;
export type WildcardHandler<T = Record<string, unknown>> = (
	type: keyof T,
	event: T[keyof T]
) => void;

// An array of all currently registered event handlers for a type
export type EventHandlerList<T = unknown> = Array<Handler<T>>;
export type WildCardEventHandlerList<T = Record<string, unknown>> = Array<WildcardHandler<T>>;

// A map of event types and their corresponding event handlers.
export type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<
	keyof Events | '*',
	EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>
>;

export interface Emitter<Events extends Record<EventType, unknown>> {
	all: EventHandlerMap<Events>;

	on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;
	on(type: '*', handler: WildcardHandler<Events>): void;

	off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void;
	off(type: '*', handler: WildcardHandler<Events>): void;

	emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;
	emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void;
}

二、ts解析

export type EventType = string | symbol

定义EventType的两种类型,string与symbol

export type Handler<T = unknown> = (event: T) => void;

定义Hanler类型,使用泛型, 类型未确定, 返回void 这里说下unknonw与any的区别

unknonw与any的区别

  • 首先任何类型的值都能赋值给any和unknown
  • 但是相对而言,any什么都不检查,unknown会进行类型检查
  • 不能将unknown类型直接赋值给其他类型,需要通过断言来修饰 image.png

修饰后的赋值

image.png

export type WildcardHandler<T = Record<string, unknown>> = (
	type: keyof T,
	event: T[keyof T]
) => void;


类型WildcardHandler 使用泛型定义Record构造一个对象类型,其属性键为Keys,它的类型为string,其属性值为Type,它的类型为unknown,返回为void

keyof T

索引类型操作符,keyof T是指限制为T上已知的公共属性名的联合

例子如下

const nameInfo1 = (obj: User, key: keyof User): User[keyof User] => {
  console.log(obj[key]) // 1111
  return obj[key] 
}
nameInfo1({ name: '积雷山摩云洞', age: 1111 }, 'age')

Record<key, value>

Record构造一个对象类型,其属性键为Keys,其属性值为Type,Record 后面的泛型就是对象键和值的类型

interface CatInfo {
  age: number;
  breed: string;
}

type CatName = 'miffy' | 'boris' | 'mordred'

const cats: Record<CatName, CatInfo> = {
  miffy: { age: 10, breed: 'Persian' },
  boris: { age: 5, breed: 'Maine Coon' },
  mordred: { age: 16, breed: 'British Shorthair' }
}
console.log(cats.boris) // { age: 5, breed: 'Maine Coon' }


export type EventHandlerList<T = unknown> = Array<Handler<T>>;
export type WildCardEventHandlerList<T = Record<string, unknown>> = Array<WildcardHandler<T>>;

定义EventHandlerList与WildCardEventHandlerList的类型,这是依然使用了泛型,构造了对象的类型

Array<T>

数组的泛型定义

interface UserItems {
  name: string;
  age: number;
}

interface User {
  UserList: Array<UserItems>
}


export type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<
	keyof Events | '*',
	EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>
>;

这里是EventHandlerMap做了定义,使用extend继承一个Record对象, 该对象的两个参数一个是限制为Events上已知的公共属性名的联合或者*, 另外一个参数要是是EventHandlerList或者是WildCardEventHandlerList

extends

extends可以继承父类的属性

image.png

这里能看到User继承了UserId的属性


export interface Emitter<Events extends Record<EventType, unknown>> {
	all: EventHandlerMap<Events>;

	on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;
	on(type: '*', handler: WildcardHandler<Events>): void;

	off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void;
	off(type: '*', handler: WildcardHandler<Events>): void;

	emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;
	emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void;
}

这是声明Emitter的类型,这个类型的泛型是Events继承一个Record对象,该对象的key为EventType, value为unknown

该类型只有四个属性分别是 all:类型定义为EventHandlerMap on:key继承 限制为Events上已知的公共属性名的联合, 有两个参数:type和handle,type的默认值为*, handler的类型又由Events[Key]来约束,同时该函数没有返回,. off:也和on类型,只是handler参数并不是必填参数,一样没有返回 emit:事件的发布,key继承 限制为Events上已知的公共属性名的联合, type可以类型匹配key或者never

never

never类型表示的是那些永不存在的值的类型。never类型是任何类型的子类型。 一般用来定义抛出异常或者根本不会有返回值的函数表达式或者箭头函数表达式的返回值类型,声明变量也可以,当他们被用不为真的类型保护所约束时。

never 和 void 的区别

void 表示没有任何类型(可以被赋值为 null 和 undefined) never 表示一个不包含值的类型,即表示永远不存在的值。 拥有 void 返回值类型的函数能正常运行。拥有 never 返回值类型的函数无法正常返回,无法终止,或会抛出异常。

类型匹配

简单的类型匹配

const name1 = '积雷山摩云洞'
const age1 = 1
console.log(name1, age1) // 积雷山摩云洞  1

type params<T> = T extends number ? number: string
type name2 = params<string>
type age2 = params<number>
const nameParam:name2 = '积雷山摩云洞'
const ageParams:age2 = 1
console.log(nameParam, ageParams) // 积雷山摩云洞 1

以上是所有的解答,如有不对之处,请留言,感谢感谢!