typescript之泛型的高级使用 - 给函数声明参数和返回值

背景和问题描述

先描述一下背景,简化一下问题

有一个 事件注册函数 on 和 触发函数 emit

function on(name: string, listener: (data?: any));
function emit(name: string, data?: any);

其中name 和 data 参数是一一对应的,

现在有以下 name - data type的map

interface EventMap{
	event1: {e1: string};
	event2: {e2: number};
}

现在希望 声明一下 on和emit 方法,使ts能够准确的进行报错和类型判断,希望达到的效果如下

emit('event1', {}); // 报错
emit('event2', {}); // 报错
emit('event3', {}); // 不报错,自定义事件

on('event1', (d)=>{}) // d 类型为 {e1: string}
on('event2', (d)=>{}) // d 类型为 {e2: number}
on('event3', (d)=>{}) // d 类型为 any

解决方案

这里我们通过泛型 + keyof + 查找类型 来实现,先上实现代码

interface EventMap {
	event1: {e1: string};
	event2: {e2: number};
	[prop: string]: any; // 用来支持自定义事件
}

export type EventRegister =
  <Key extends keyof EventMap>(name: Key, listener: (data: IMap[Key])=>void) => void;

export type EventEmitter =
  <Key extends keyof EventMap>(name: Key | string, data?: IMap[Key]) => void;

使用:

const on: EventRegister = (name, listener) => {
};
const emit: EventEmitter = (name, data) => {
};

讲解一下这一句,首先通过函数前置泛型声明了一个 Key 继承map的键,然后在函数参数定义中声明name为map的键,listener 参数data声明为 map对应的值类型

export type EventRegister =
  <Key extends keyof EventMap>(name: Key, listener: (data: IMap[Key])=>void) => void;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值