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 相关文章推荐
用roll.js实现的图片自动滚动+鼠标触动的特效
Mar 18 Javascript
JavaScript对象模型-执行模型
Apr 28 Javascript
Javascript 继承实现例子
Aug 12 Javascript
js数组Array sort方法使用深入分析
Feb 21 Javascript
javascript中的void运算符语法及使用介绍
Mar 10 Javascript
js实现html table 行,列锁定的简单实例
Oct 13 Javascript
js实现导航栏中英文切换效果
Jan 16 Javascript
基于require.js的使用(实例讲解)
Sep 07 Javascript
js表单序列化判断空值的实例
Sep 22 Javascript
Vue实现动态添加或者删除对象和对象数组的操作方法
Sep 21 Javascript
jQuery实现适用于移动端的跑马灯抽奖特效示例
Jan 18 jQuery
Cordova(ionic)项目实现双击返回键退出应用
Sep 17 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
php中autoload的用法总结
2013/11/08 PHP
ecshop实现smtp发送邮件
2015/02/03 PHP
PHP中SSO Cookie登录分析和实现
2015/11/06 PHP
[原创]php token使用与验证示例【测试可用】
2017/08/30 PHP
postman的安装与使用方法(模拟Get和Post请求)
2018/08/06 PHP
JavaScript 闭包在封装函数时的简单分析
2009/11/28 Javascript
javascript 判断中文字符长度的函数代码
2012/08/27 Javascript
Node.js中require的工作原理浅析
2014/06/24 Javascript
JQuery设置时间段下拉选择实例
2014/12/30 Javascript
JS实现可调整倒计时间代码分享
2015/08/18 Javascript
JS实现自动定时切换的简洁网页选项卡效果
2015/10/13 Javascript
js判断当前页面用什么浏览器打开的方法
2016/01/06 Javascript
webuploader模态框ueditor显示问题解决方法
2016/12/27 Javascript
canvas快速绘制圆形、三角形、矩形、多边形方法介绍
2016/12/29 Javascript
使用JS动态显示文本
2017/09/09 Javascript
javascript用rem来做响应式开发
2018/01/13 Javascript
Express之托管静态文件的方法
2018/06/01 Javascript
select2 ajax 设置默认值,初始值的方法
2018/08/09 Javascript
JS表格的动态操作完整示例
2020/01/13 Javascript
修改vue源码实现动态路由缓存的方法
2020/01/21 Javascript
简单了解vue 插值表达式Mustache
2020/07/22 Javascript
VUE中setTimeout和setInterval自动销毁案例
2020/09/07 Javascript
修改NPM全局模式的默认安装路径的方法
2020/12/15 Javascript
[00:33]2016完美“圣”典风云人物:Sccc宣传片
2016/12/03 DOTA
Python实现购物程序思路及代码
2017/07/24 Python
浅谈pytorch和Numpy的区别以及相互转换方法
2018/07/26 Python
django2.2安装错误最全的解决方案(小结)
2019/09/24 Python
Python 分布式缓存之Reids数据类型操作详解
2020/06/24 Python
使用sublime text3搭建Python编辑环境的实现
2021/01/12 Python
详解纯CSS3制作的20种loading动效
2017/07/05 HTML / CSS
生产部主管岗位职责
2014/01/06 职场文书
上课玩手机的检讨书
2014/10/01 职场文书
2014年电教工作总结
2014/12/19 职场文书
学术研讨会欢迎词
2015/01/26 职场文书
申请吧主发表的感言
2015/08/03 职场文书
MySQL 开窗函数
2022/02/15 MySQL