TypeScript 使用 Tuple Union 声明函数重载

 更新时间:2022年04月07日 16:24:17   作者:vilicvane  
这篇文章主要介绍了TypeScript 使用 Tuple Union 声明函数重载,TypeScript 中为函数添加多个签名后,依然需要添加相应的代码来判断并从不同的签名参数列表中获取对应的参数,下文就来探索方法和技巧吧

问题:

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 声明函数重载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • js实现简单购物车模块

    js实现简单购物车模块

    这篇文章主要为大家详细介绍了js实现简单购物车模块,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-04-04
  • JavaScript块级作用域绑定的实现流程

    JavaScript块级作用域绑定的实现流程

    这篇文章主要给大家介绍了关于JavaScript块级作用域绑定的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-12-12
  • js中window.open()的所有参数详细解析

    js中window.open()的所有参数详细解析

    本篇文章主要是对js中window.open()的所有参数进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-01-01
  • 原生JS实现的自动轮播图功能详解

    原生JS实现的自动轮播图功能详解

    这篇文章主要介绍了原生JS实现的自动轮播图功能,结合实例形式详细分析了基于原生js实现轮播图的原理、操作步骤及操作注意事项,需要的朋友可以参考下
    2018-12-12
  • 原生js实现电子时钟

    原生js实现电子时钟

    这篇文章主要为大家详细介绍了原生js实现电子时钟,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • js多级树形弹出一个小窗口层(非常好用)实例代码

    js多级树形弹出一个小窗口层(非常好用)实例代码

    js多级树形弹出一个小窗口层(非常好用)实例代码,需要的朋友可以参考一下
    2013-03-03
  • el-table解决过滤导致选中的丢失的问题

    el-table解决过滤导致选中的丢失的问题

    在使用Element UI的el-table组件时,可能会遇到过滤数据后选中状态丢失的问题,解决这一问题的关键在于利用Vue的计算属性和事件绑定功能,感兴趣的朋友跟随小编一起看看吧
    2024-09-09
  • JavaScript异步加载浅析

    JavaScript异步加载浅析

    这篇文章主要介绍了JavaScript异步加载浅析,本文讲解了脚本延迟执行、脚本的完全并行化、可编程的脚本加载等内容,需要的朋友可以参考下
    2014-12-12
  • 微信提示 在浏览器打开 效果实现过程解析

    微信提示 在浏览器打开 效果实现过程解析

    这篇文章主要介绍了微信提示 在浏览器打开 效果实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • 可以拖动的div 实现代码

    可以拖动的div 实现代码

    可以拖动的div是一个比较难以做到的效果,特别是在浏览器对于js代码的运行效率还不是足够高的情况下,不过听说firefox对于js的支持正在增加,大概是料到了js在网页浏览的桌面化趋势中所占的重要地位吧。
    2009-06-06

最新评论