TypeScript 使用 Tuple Union 声明函数重载


Posted in Javascript onApril 07, 2022

问题:

TypeScript 中为函数添加多个签名后,依然需要添加相应的代码来判断并从不同的签名参数列表中获取对应的参数。过去常见的写法:

function refEventEmitter(event?: string): void;
function refEventEmitter(event: string, callback: () => void): void;
function refEventEmitter(callback: () => void): void;
function refEventEmitter(
  eventOrCallback?: string | (() => void),
  callback?: () => void,
): void {
  let event: string | undefined;

  if (typeof eventOrCallback === 'function') {
    callback = eventOrCallback;
  } else {
    event = eventOrCallback;
  }

  // ...
}

这个过程因为将原有参数列表直接按序号拍平,参数之间的类型关联需要人肉确保正确。

技巧:

这时我们可以通过使用tuple union 的参数类型,来无脑处理各种函数重载情况:

function refEventEmitter(event?: string): void;
function refEventEmitter(event: string, callback: () => void): void;
function refEventEmitter(callback: () => void): void;
function refEventEmitter(
  ...args:
    | [event?: string]
    | [
        event: string,
        callback: () => unknown,
      ]
    | [callback: () => unknown]
): void {
  let [event, callback] =
    args.length === 2
      ? args
      : typeof args[0] === 'function'
      ? [undefined, args[0]]
      : [args[0], undefined];

  // ...
}

实际上,此时上方的签名列表也不再需要了:

function refEventEmitter(
  ...args:
    | [event?: string]
    | [
        event: string,
        callback: () => unknown,
      ]
    | [callback: () => unknown]
): void {
  let [event, callback] =
    args.length === 2
      ? args
      : typeof args[0] === 'function'
      ? [undefined, args[0]]
      : [args[0], undefined];

  // ...
}
这篇其实拖了有点久,在写的时候发现 TypeScript 已经内置了 "Convert overload list to single signature" 的重构选项,可以一键将重载列表变为参数 tuple union。

不过到这里其实还存在问题,TypeScript 中 typeof 条件判断不能对整个对象进行收窄,只能收窄被 typeof 到的某个元素、属性。上面的例子中,如果需要的不只是 args[0] 就会出现问题。

此时我们可以引入一个工具函数 isTypeOfProperty(object, key, type)

此时实现就变成了:

function refEventEmitter(
  ...args:
    | [event?: string]
    | [
        event: string,
        callback: () => unknown,
      ]
    | [callback: () => unknown]
): void {
  let [event, callback] =
    args.length === 2
      ? args
      : isTypeOfProperty(args, 0, 'function')
      ? [undefined, args[0]]
      : [args[0], undefined];

  // ...
}

到此这篇关于TypeScript 使用 Tuple Union 声明函数重载的文章就介绍到这了,更多相关TypeScript 声明函数重载内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
jquerymobile checkbox及时刷新才能获取其准确值
Apr 14 Javascript
JS解决url传值出现中文乱码的另类办法
Apr 08 Javascript
jQuery基于当前元素进行下一步的遍历
May 20 Javascript
Javascript编写2048小游戏
Jul 07 Javascript
基于jQuery实现照片墙自动播放特效
Jan 12 Javascript
微信小程序 网络请求(post请求,get请求)
Jan 17 Javascript
jQuery EasyUI结合zTree树形结构制作web页面
Sep 01 jQuery
vue.js实现点击后动态添加class及删除同级class的实现代码
Apr 04 Javascript
Vue中如何实现proxy代理
Apr 20 Javascript
vue-swiper的使用教程
Aug 30 Javascript
基于javascript的拖拽类封装详解
Apr 19 Javascript
javascript用defineProperty实现简单的双向绑定方法
Apr 03 Javascript
Axios代理配置及封装响应拦截处理方式
vue-cil之axios的二次封装与proxy反向代理使用说明
Apr 07 #Vue.js
动态规划之使用备忘录来改进Javascript函数
Apr 07 #Javascript
vue实现拖拽交换位置
Apr 07 #Vue.js
使用Ajax实现进度条的绘制
Vue.Draggable实现交换位置
vue-cli3.0修改打包后的文件名和文件地址,打包后本地运行报错解决
You might like
CodeIgniter使用phpcms模板引擎
2013/11/12 PHP
PHP封装的多文件上传类实例与用法详解
2017/02/07 PHP
PHP+Redis开发的书签案例实战详解
2019/07/09 PHP
JavaScript 乱码问题
2009/08/06 Javascript
原创javascript小游戏实现代码
2010/08/19 Javascript
网页前端优化之滚动延时加载图片示例
2013/07/13 Javascript
jQuery学习笔记之 Ajax操作篇(三) - 过程处理
2014/06/23 Javascript
js交换排序 冒泡排序算法(Javascript版)
2014/10/04 Javascript
jQuery Easy UI中根据第一个下拉框选中的值设置第二个下拉框是否可以编辑
2016/11/29 Javascript
原生js编写焦点图效果
2016/12/08 Javascript
ES6中Array.find()和findIndex()函数的用法详解
2017/09/16 Javascript
JavaScript实现图片本地预览功能【不用上传至服务器】
2017/09/20 Javascript
实现单层json按照key字母顺序排序的示例
2017/12/06 Javascript
vue2.0.js的多级联动选择器实现方法
2018/02/09 Javascript
Vue利用canvas实现移动端手写板的方法
2018/05/03 Javascript
对angularJs中$sce服务安全显示html文本的实例
2018/09/30 Javascript
vue使用laydate时间插件的方法
2018/11/14 Javascript
详解JS实现系统登录页的登录和验证
2019/04/29 Javascript
详解如何写出一个利于扩展的vue路由配置
2019/05/16 Javascript
vue学习笔记之slot插槽用法实例分析
2020/02/29 Javascript
在Python中处理字符串之isdecimal()方法的使用
2015/05/20 Python
django实现分页的方法
2015/05/26 Python
flask框架使用orm连接数据库的方法示例
2018/07/16 Python
Python产生一个数值范围内的不重复的随机数的实现方法
2019/08/21 Python
使用 Python 清理收藏夹里已失效的网站
2019/12/03 Python
解决python 找不到module的问题
2020/02/12 Python
HTML5标签与HTML4标签的区别示例介绍
2013/07/18 HTML / CSS
幼儿园园长岗位职责
2013/11/26 职场文书
施工班组长岗位职责
2014/01/05 职场文书
美容院经理岗位职责
2014/04/03 职场文书
工程售后服务承诺书
2014/05/21 职场文书
科级干部群众路线教育实践活动对照检查材料思想汇报
2014/09/20 职场文书
药店收银员岗位职责
2015/04/07 职场文书
MySQL 视图(View)原理解析
2021/05/19 MySQL
Python爬虫实战之爬取京东商品数据并实实现数据可视化
2021/06/07 Python
MongoDB 常用的crud操作语句
2021/06/20 MongoDB