TypeScript 如何定义函数类型

不管是写网页交互的点击事件,还是做数据处理的工具函数,写代码时最常碰到的就是“函数”。但如果只是随便写一个函数,比如写了个计算工资的函数,最后传进去的参数是个字符串,返回的结果是NaN,就很容易出bug。这时候TypeScript的“函数类型定义”就能派上用场——它就像给函数写了一份“使用说明书”,告诉代码“这个函数要收什么样的参数,要返回什么东西”,从根源上减少这类莫名其妙的错误。

先搞懂最基础的:给参数和返回值定规矩

很多人刚接触TypeScript,会把函数的类型定义拆成两部分:参数的类型和返回值的类型,这两部分都得说清楚,不然就像外卖没写“少放辣”,结果和想要的不一样。

TypeScript 如何定义函数类型

比如我们要写一个计算奶茶总价的函数,一杯奶茶15元,买几杯算几杯的钱。如果用JavaScript写,可能是这样:

`javascript

function calcMilkTeaPrice(quantity) {

return quantity * 15;

}

`

但如果传calcMilkTeaPrice("3")进去,会返回"315"(字符串拼接),传calcMilkTeaPrice(undefined)会返回NaN,全是坑。换成TypeScript,给参数和返回值定规矩就简单:

`typescript

function calcMilkTeaPrice(quantity: number): number {

return quantity * 15;

}

`

这里的quantity: number就是给参数“定类型”,只能传数字;最后的: number是“定返回值类型”,函数必须返回数字。现在再传"3",代码会直接报错,不用等运行的时候才发现问题。

给函数本身定类型:像给变量“贴标签”

有时候我们会把函数当成变量用——比如把奶茶定价的函数传给另一个“算总费用”的工具函数,或者把它存到对象里。这时候直接用上面的写法,TypeScript可能会搞不清“这个变量到底是啥类型”,就像把“奶茶店的菜单”当成“奶茶杯”拿,会出错。

这时候可以给这个函数变量直接定类型,就像给它贴一个“只能放符合要求的函数”的标签。还是拿奶茶举例,我们要定义一个“接受数字参数、返回数字的函数”类型,用(参数类型) => 返回值类型的写法:

`typescript

// 定义一个函数类型:叫PriceCalc,参数是number,返回是number

type PriceCalc = (quantity: number) => number;

// 把calcMilkTeaPrice的类型定为PriceCalc

const milkTeaPrice: PriceCalc = calcMilkTeaPrice;

// 或者直接写函数

const milkTeaPrice: PriceCalc = (q) => q * 15;

`

现在如果把一个传字符串的函数塞进去,比如const wrongFunc: PriceCalc = (q) => "太贵了",TypeScript会直接报错——因为返回的是字符串,不符合PriceCalc要求的返回数字。

处理有“可选参数”的情况:给“可选的小料”留位置

很多函数会有可选参数,比如买奶茶可以选“加珍珠”,加不加都可以,不加也不会报错。用TypeScript定义这种情况也很简单,在参数后面加个?就行。

比如我们要写一个“算奶茶总价+可选打包费”的函数,打包费2元,可选:

`typescript

function calcMilkTeaPrice(quantity: number, isPackaging?: boolean): number {

const base = quantity * 15;

// 如果传了isPackaging为true,就加2元打包费,否则不加

return isPackaging ? base + 2 : base;

}

`

如果不传第二个参数,比如calcMilkTeaPrice(2),TypeScript不会报错,因为isPackaging是可选的;但如果传了calcMilkTeaPrice(2, "是"),就会报错——因为要求传布尔值,传了字符串,和加珍珠要的是“加/不加”,不是“要/不要”是一个道理。

函数里的特殊情况:允许传“多种类型”的参数

有时候参数可能有好几种类型,比如奶茶的数量可以是直接的数字,也可以是写在菜单上的字符串(比如“小杯=1”“大杯=2”)。这时候可以用“联合类型”,用|分隔,就像说“你可以选小杯或大杯”。

`typescript

function calcMilkTeaPrice(quantity: number | string): number {

// 如果是字符串就转成数字,比如"小杯"转成1

const num = typeof quantity === "string" ? 1 : quantity;

return num * 15;

}

`

现在传calcMilkTeaPrice("小杯")或者calcMilkTeaPrice(3)都不会报错,符合“数量可以是数字或代表规格的字符串”的需求。

简单来说,TypeScript定义函数类型,本质就是给函数的“输入(参数)”和“输出(返回值)”定清楚规则,再把函数变量的类型也明确下来,就像给奶茶店的流程定好规矩:点单要报清楚杯数(参数),结账要算对钱(返回值),不会出现“拿错奶茶、算错钱”的乌龙,写代码也能少踩很多坑。

上一篇 Java 如何做并发控制