# TS函数重载

108 阅读2分钟

TS函数重载

typescript.jpeg

在TS中,允许我们为同一个函数提供多个函数类型定义,从而实现函数重载,从而实现函数根据不同的参数类型,返回不同的类型,从而实现函数的复用,但是需要注意的是,函数重载的实现需要配合函数实现体来实现,否则会报错,第二个需要注意的是,函数重载的实现需要按照从上到下的顺序来实现,否则会报错,尤其是对于空值的申明位置,需要放在最后,否则会报错,因为空值是所有类型的父类,如果放在前面,那么所有的类型都会被当作空值来处理,从而失去了函数重载的意义;第三,在申明TS重载申明后,要紧跟去实现函数体, 且中间不能申明其他类型,否则可能会报 Function implementation is missing or not immediately following the declaration.ts(2391)错误;

1. 函数重载

在下面这个例子中, 其实就是通过参数类型来推到出返回值类型,从而实现函数重载,且可以根据参数,申明多个函数类型,从而实现函数的复用

function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: string, b: number): string;
function add(a: number, b: string): string;
function add(a: Combinable, b: Combinable) {
  return a + b;
}

2. 举一个业务中的例子吧

flatUploadUrl中,其实就根据两个参数来推导要返回的类型, 具体分三种种情况,分别是:

  • 1 如果传入url, 则返回一个Array<{ url: string, uid: string }>这样一个数组类型
  • 2 如果传入fileList数组, 则返回一个将fileList遍历后将每一项的url拼接其他的一个string类型
  • 3 如果没有传入url,或者fileList,则返回一个undefined
// 如果传入url, 则返回一个Array<{ url: string, uid: string }>这样一个数组类型
interface FlatUploadUrlPropsByUrl {
  dot?: string
  url: string
  fileList?: undefined
}

// 如果传入fileList数组, 则返回一个将fileList遍历后将每一项的url拼接其他的一个string类型
interface FlatUploadUrlPropsByFileList {
  dot?: string
  fileList: UploadRequestFile[]
  url?: undefined
}

// 如果没有传入url,或者fileList,则返回一个undefined
interface FlatUploadUrlPropsEmpty {
  dot?: string
  url?: string
  fileList?: undefined
}

type FlatUploadUrlProps = FlatUploadUrlPropsByUrl | FlatUploadUrlPropsByFileList | FlatUploadUrlPropsEmpty

type FlatUploadUrlResult = string | Array<{ url: string; uid: string }> | undefined

function flatUploadUrl(props: FlatUploadUrlPropsByFileList): string
function flatUploadUrl(props: FlatUploadUrlPropsByUrl): Array<{ url: string; uid: string }>
function flatUploadUrl(props: FlatUploadUrlPropsEmpty): undefined

/**
 * @param {String } url - 后端返回的图片地址
 * @param {String } dot - 分隔符, 在url中的分割符
 * @param {Array } fileList - 上传的文件列表
 * @returns string | Array<{ url: string; uid: string }> | undefined
 */
function flatUploadUrl({ url, dot, fileList }: FlatUploadUrlProps): FlatUploadUrlResult {
  const d = dot || ','
  if (url && Object.prototype.toString.call(url) === '[object String]') {
    return url?.split(d).map((item, index) => ({ url: item, uid: `${index}` }))
  }
  if (Array.isArray(fileList)) {
    return fileList.map((item) => item.url).join(d)
  }
  return void 0
}

特别说明

上面开始提到过一点,如果重载申明后面没有紧跟实现体,ts会报错,下面演示一下, 还是以上面的为例

interface FlatUploadUrlPropsByUrl {
  dot?: string
  url: string
  fileList?: undefined
}

interface FlatUploadUrlPropsByFileList {
  dot?: string
  fileList: UploadRequestFile[]
  url?: undefined
}

interface FlatUploadUrlPropsEmpty {
  dot?: string
  url?: string
  fileList?: undefined
}

type FlatUploadUrlProps = FlatUploadUrlPropsByUrl | FlatUploadUrlPropsByFileList | FlatUploadUrlPropsEmpty

type FlatUploadUrlResult = string | Array<{ url: string; uid: string }> | undefined

function flatUploadUrl(props: FlatUploadUrlPropsByFileList): string
function flatUploadUrl(props: FlatUploadUrlPropsByUrl): Array<{ url: string; uid: string }>
function flatUploadUrl(props: FlatUploadUrlPropsEmpty): undefined

type a = string | number

const b: a = 3

console.log('b :>> ', b);

function flatUploadUrl({ url, dot, fileList }: FlatUploadUrlProps): FlatUploadUrlResult {
  const d = dot || ','
  if (url && Object.prototype.toString.call(url) === '[object String]') {
    return url?.split(d).map((item, index) => ({ url: item, uid: `${index}` }))
  }
  if (Array.isArray(fileList)) {
    return fileList.map((item) => item.url).join(d)
  }
  return void 0
}

如下图所示

image.png