函数类型(Function)
函数类型概述
TypeScript 中的函数类型包含参数类型和返回值类型,用于类型检查和代码提示。
声明式函数
核心语法:
TypeScript
function 函数名(参数1: 类型, 参数2: 类型): 返回值类型 {
return 返回值;
}1
2
3
2
3
参数类型注解
- 直接写在参数名后
arg1: number - 支持所有 TypeScript 类型(string, boolean, object, 自定义类型等)
- 可选参数使用
?标记
TypeScript
function getMessage(name: string, age?: number): string {
return age ? `你好${name},你今年 ${age}岁` : `你好${name}`;
}1
2
3
2
3
返回值类型注解
- 直接写在函数名后
(): number - 无返回值时使用
void
TypeScript
function logMessage(msg: string): void {
console.log(msg);
}1
2
3
2
3
调用规则
TypeScript
function add(arg1: number, arg2: number): number {
return arg1 + arg2;
}1
2
3
2
3
- 必须传递所有非可选参数
TypeScript
add(2, 3) // ✅
add(1) // ❌ 参数不足1
2
2
- 参数类型必须严格匹配
TypeScript
add(1, "text") // ❌ 类型错误1
- 支持默认参数
TypeScript
function add(a: number, b: number = 2): number {
return a + b;
}1
2
3
2
3
- 支持剩余参数
TypeScript
function sum(...numbers: number[]): number {
return numbers.reduce((acc, curr) => acc + curr, 0);
}1
2
3
2
3
箭头函数
核心语法:
TypeScript
const 函数名 = (参数1: 类型, 参数2: 类型): 返回值类型 => {
// 函数体
return 返回值;
};1
2
3
4
2
3
4
参数类型注解
- 参数类型:
(a: number, b: number) - 返回值类型:
: number(在参数括号后)
this 绑定差异
- 箭头函数没有自己的
this,会继承外层作用域的this - 传统函数的
this取决于调用方式
常见错误
TypeScript
// 错误1:遗漏返回值类型
const add = (a: number, b: number) => a + b; // 可以但不推荐
// 错误2:错误使用this
const counter = {
count: 0,
increment: () => {
this.count++; // 错误!箭头函数的this指向外层
}
};1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
函数类型别名
使用类型别名定义函数类型,提高代码可读性和复用性。
TypeScript
// 普通写法
const handlers: ((msg: string) => void)[] = [];
// 使用类型别名
type MessageHandler = (msg: string) => void;
const handlers: MessageHandler[] = [];1
2
3
4
5
6
2
3
4
5
6
高级用法
联合函数类型:
TypeScripttype StringProcessor = | ((input: string) => string) | ((input: string[]) => string[]);1
2
3泛型函数类型:
TypeScripttype Mapper<T, U> = (item: T) => U; const numberToString: Mapper<number, string> = (n) => n.toString();1
2复杂函数签名:
TypeScripttype EventListener = { (type: 'click', handler: (e: MouseEvent) => void): void; (type: 'keypress', handler: (e: KeyboardEvent) => void): void; };1
2
3
4
最佳实践建议
项目规范:
- 对重复使用的函数类型定义统一别名
- 将常用类型别名集中存放在
types.ts文件中
命名约定:
- 使用
Handler/Callback/Processor等后缀 - 泛型类型使用
T/U等约定俗成的类型参数
- 使用
文档注释:
TypeScript/** * 用户认证函数类型 * @param credentials - 认证凭据 * @returns 认证令牌或null */ type AuthFunction = (credentials: Credentials) => string | null;1
2
3
4
5
6
泛型函数
泛型函数允许我们编写可重用的函数,支持多种类型。
TypeScript
function identityFn<T>(arg: T): T {
return arg;
}
const identity = <T>(arg: T): T => arg;
// 使用示例
const result1 = identityFn<number>(123);
const result2 = identityFn<string>("hello");1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
异步函数
异步函数返回 Promise 类型,使用 async 和 await 语法。
TypeScript
interface User {
id: number;
name: string;
}
async function fetchUser(id: number): Promise<User> {
const response = await fetch(`/api/users/${id}`);
return await response.json();
}
const fetchUserAsync = async (id: number): Promise<User> => {
const response = await fetch(`/api/users/${id}`);
return await response.json();
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
函数签名
概念
函数签名(Function Signature)是指函数的参数和返回值类型。在 TypeScript 中,函数签名用于定义函数的类型,包括参数和返回值的类型。
三大要素
函数名标识
- 命名需符合语义化原则
- 示例:
parseInput比parse更明确
参数类型列表
- 包含参数顺序和类型约束
- 支持复杂类型:
TypeScriptinterface Coordinate { x: number; y: number; } function moveTo(pos: Coordinate): void;1
2
3
4
5返回值类型
- 明确函数输出契约
- 特殊类型示例:
TypeScript// 异步函数签名 function createLoader(): () => Promise<Data>;1
2
签名与实现的区别
TypeScript
// 签名(类型层面)
type FetchSignature = (url: string, init?: RequestInit) => Promise<Response>;
// 实现(值层面)
const fetch: FetchSignature = async (url, init) => { /*...*/ };1
2
3
4
5
2
3
4
5
示例
TypeScript
// 定义一个计算器签名
type Calculator = {
(a: number, b: number): number; // 基础运算
(a: string, b: string): string; // 字符串拼接
(values: number[]): number; // 数组求和
};1
2
3
4
5
6
2
3
4
5
6
调用签名
在接口中描述函数的调用方式,包括参数和返回值类型。
当函数需要同时具有属性或方法时使用
TypeScript
// 调用签名(包含属性)
interface AddFunction {
(a: number, b: number): number; // 函数签名
count: number; // 属性
reset: () => void; // 方法
}
function createAddFunction(): AddFunction {
const addFn = function(a: number, b: number): number {
addFn.count++;
return a + b;
} as AddFunction;
addFn.count = 0;
addFn.reset = () => {
addFn.count = 0;
};
return addFn;
}
// 使用
const add = createAddFunction();
console.log(add(1, 2)); // 3
console.log(add.count); // 1
add.reset();
console.log(add.count); // 01
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
构造签名
描述使用 new 关键字创建实例时的参数和返回值类型。
定义构造函数的类型,用于类或构造函数的类型检查
TypeScript
// 构造签名
interface Constructor {
new (a: number, b: number): { a: number, b: number };
}
const MyClass: Constructor = class {
constructor(public a: number, public b: number) {}
};
// 使用
const instance = new MyClass(1, 2);
console.log(instance.a, instance.b); // 1 21
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
类型与实现分离
类型与实现分离是 TypeScript 中的重要概念,允许我们先定义函数的类型接口,然后再实现具体的函数。这样可以提高代码的可维护性和可读性,特别是在大型项目中。
基本用法
TypeScript
// 声明函数类型变量
let addFn: (a: number, b: number) => number;
// 实现函数
addFn = (a, b) => a + b;1
2
3
4
5
2
3
4
5
关键特性
类型安全保证:
- 所有赋值必须符合声明的函数类型
- 参数数量和类型必须严格匹配
- 返回值类型必须一致
参数名自由性:
TypeScripttype Comparator = (a: string, b: string) => number; // 参数名可以不同但类型必须匹配 const compare: Comparator = (str1, str2) => str1.length - str2.length;1
2
3
4错误示例:
TypeScriptlet operation: (n: number) => string; operation = (num: number) => num * 2; // 错误:返回值应该是string1
2

