ts中如何描述一个复杂函数的类型

函数重载

函数重载可以描述复杂的函数类型

ts 复制代码
function fn(num: number): number
function fn(str: string): string

function fn(arg: number | string) {
  if (typeof arg === 'number') return 0
  return '1'
}

不过这种方法适用范围有限 不能导出一个类型用于定义其他函数 而且需要把重载的类型在参数里额外写一次

函数的调用类型

也可以直接描述其调用类型

ts 复制代码
type FN = {
  (num: number): number
  (str: string): string
}

但这个类型只能用于描述函数 不能用于定义函数 会让ts对类型产生误判

ts 复制代码
const fn: FN = (arg) => {
  if (typeof arg === 'number') return 0
  return '1'
}

如果将回调函数声明为这个类型 写代码的时候会完全失去类型提示

TypeMap构造函数参数

ts 复制代码
type ArgMap = {
  number: { num: number }
  string: { str: string }
}

type FN = (
  config: {
    [K in keyof ArgMap]: ArgMap[K] & {
      type: K
    }
  }[keyof ArgMap],
) => void

const fn: FN = (config) => {
  switch (config.type) {
    case 'string':
      console.log(config.str)
      break
    case 'number':
      console.log(config.num)
  }
}

可以利用类型索引自由构造不同类型的参数 这里构造为对象并用type区分并不强制 甚至可以构造args数组

类型非常完备 但无法约束返回值

TypeMap+泛型

typescript 复制代码
type FN = <K extends keyof FnTypeMap>(type: K, value: FnTypeMap[K]['in']) => FnTypeMap[K]['out']

const fn: FN = (type, value) => {
  switch (type) {
    case 'number': {
      value // FnTypeMap[K]["in"] 并没有收窄类型
      break
    }
    case 'string': {
      break
    }
  }
}

类型依旧不完备

结论

复杂函数类型在ts中没有一个完美的解决方案 定义函数时重载即可 需要以一个类型约束函数的时候(例如描述回调函数或者使用zustand时)使用TypeMap构造参数对象 可以用onComplete等替代返回值

相关推荐
程序员黑豆37 分钟前
Java包装类:基本类型与对象的桥梁
java·前端·ai编程
bugcome_com3 小时前
JWT 知识小课堂:从入门到精通,一文吃透 JSON Web Token
前端·json
To_OC3 小时前
写了三天 Next.js,我的 React 世界观被拆了又装回去
前端·全栈·next.js
独泪了无痕4 小时前
viewer.js 安装与配置指南:实现图片预览功能
前端·vue.js
用户938515635075 小时前
实战 Todo CRUD —— 从路由到异常,手写一个完整模块
后端·typescript·nestjs
Fluxart.ai6 小时前
电商商品图审核怎么自动化?规则引擎、人工复核与发布门禁
java·前端·自动化
why技术6 小时前
AI 写的文章,可能都带着手敲一遍都去不掉的“隐形水印”。
前端·人工智能·后端
愚公搬代码6 小时前
【愚公系列】《Android应用案例开发大全》016-LBS类应用掌上杭州(辅助工具类的开发)
android·前端
CodeSheep6 小时前
又一个华为天才少年,离职了!
前端·后端·程序员
kyriewen7 小时前
面试官说"打开你的AI工具"——我才发现,他考的根本不是写代码
前端·人工智能·面试