核心目的: 函数类型用来描述一个函数应该接受什么类型的参数以及返回什么类型的值。
最常用的方式:使用类型别名 (type)
这是定义可复用函数类型最常见且推荐的方式。
-
定义函数类型别名:
使用 type 关键字,后跟类型名称,等号右边是函数的签名:(参数列表) => 返回值类型。// 定义一个类型别名 AddFunction // 它描述了一个函数:接受两个 number 类型的参数,返回一个 number 类型的值 type AddFunction = (a: number, b: number) => number; // 定义一个类型别名 GreetFunction // 它描述了一个函数:接受一个 string 类型的参数,没有返回值 (void) type GreetFunction = (message: string) => void;
-
使用类型别名注解变量:
声明一个变量,并使用你定义的类型别名来注解它。这表示该变量未来只能被赋值为符合该类型的函数。let myAdd: AddFunction; let myGreet: GreetFunction;
-
实现符合该类型的函数并赋值:
创建函数(通常使用函数表达式或箭头函数),确保其参数和返回值类型与类型别名匹配,然后将其赋值给注解过的变量。// 实现 myAdd myAdd = (x, y) => { // 参数名 x, y 不需要和类型别名中的 a, b 一样,但类型必须匹配 return x + y; }; // 实现 myGreet myGreet = (msg) => { console.log(msg); }; // 错误示例:类型不匹配会导致编译错误 // myAdd = (s1: string, s2: string) => s1 + s2; // 错误!参数类型和返回值类型都不匹配 AddFunction // myGreet = (num: number) => console.log(num); // 错误!参数类型不匹配 GreetFunction
-
调用函数:
像普通函数一样调用这些变量。let sum: number = myAdd(10, 5); // sum 的类型是 number console.log(sum); // 输出: 15 myGreet("Hello TypeScript!"); // 输出: Hello TypeScript!
另一种方式:内联类型注解
如果你只是临时用一次函数类型,不想创建可复用的类型别名,可以直接在变量声明或函数参数中写明类型。
// 直接在变量声明上注解函数类型
let multiply: (x: number, y: number) => number;
multiply = (a, b) => {
return a * b;
};
console.log(multiply(4, 5)); // 输出: 20
// 在函数参数中注解回调函数类型(非常常见!)
function processArray(arr: number[], callback: (element: number, index: number) => void): void {
for (let i = 0; i < arr.length; i++) {
// 调用回调函数时,TypeScript 会检查传入的参数是否符合 callback 的类型要求
callback(arr[i], i);
}
}
// 调用 processArray,并传入一个符合回调类型的箭头函数
processArray([1, 2, 3], (num, idx) => {
// 在这个回调函数内部,TypeScript 知道 num 是 number, idx 是 number
console.log(`Index: ${idx}, Value: ${num}`);
});
基本使用总结:
- 定义形状: 使用 type FuncType = (param1: Type1, ...) => ReturnType; 来定义一个可复用的函数类型。
- 应用类型: 使用 let myFunc: FuncType; 来声明一个变量,它必须持有符合 FuncType 的函数。
- 实现函数: 创建一个函数(通常是箭头函数或函数表达式),确保参数和返回值类型与定义的类型匹配,并赋值给变量。
- 直接注解: 对于一次性使用,可以直接在变量或参数上写 (param1: Type1, ...) => ReturnType;。