函数类型
TypeScript 为函数提供了强大的类型支持,包括参数类型、返回值类型、重载等特性。
函数类型定义
基本语法
// 函数声明
function add(a: number, b: number): number {
return a + b;
}
// 函数表达式
const subtract = function(a: number, b: number): number {
return a - b;
};
// 箭头函数
const multiply = (a: number, b: number): number => a * b;完整函数类型
// 完整的类型注解
const divide: (a: number, b: number) => number = (a, b) => a / b;
// 使用类型别名
type MathOperation = (a: number, b: number) => number;
const modulo: MathOperation = (a, b) => a % b;
// 使用接口
interface Calculator {
(a: number, b: number): number;
}
const power: Calculator = (a, b) => Math.pow(a, b);参数类型
可选参数
function greet(name: string, greeting?: string): string {
return `${greeting || "Hello"}, ${name}!`;
}
greet("Alice"); // "Hello, Alice!"
greet("Bob", "Hi"); // "Hi, Bob!"默认参数
function createUser(name: string, age: number = 18): { name: string; age: number } {
return { name, age };
}
createUser("Alice"); // { name: "Alice", age: 18 }
createUser("Bob", 25); // { name: "Bob", age: 25 }剩余参数
function sum(...numbers: number[]): number {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
sum(1, 2, 3); // 6
sum(1, 2, 3, 4, 5); // 15
// 带固定参数
function log(prefix: string, ...messages: string[]): void {
console.log(prefix, ...messages);
}解构参数
interface Options {
url: string;
method?: string;
timeout?: number;
}
function request({ url, method = "GET", timeout = 5000 }: Options): void {
console.log(`${method} ${url} (timeout: ${timeout})`);
}
request({ url: "https://api.example.com" });返回值类型
显式返回类型
function getString(): string {
return "hello";
}
function getNumber(): number {
return 42;
}
function getBoolean(): boolean {
return true;
}void 返回类型
function log(message: string): void {
console.log(message);
// 没有返回值,或返回 undefined
}
// 注意:回调函数的 void 返回类型允许返回值
const callbacks: (() => void)[] = [];
callbacks.push(() => 123); // 合法,但返回值被忽略never 返回类型
// 抛出异常
function throwError(message: string): never {
throw new Error(message);
}
// 无限循环
function infiniteLoop(): never {
while (true) {}
}类型推断
// TypeScript 会自动推断返回类型
function add(a: number, b: number) {
return a + b; // 推断为 number
}
// 复杂情况建议显式声明
function getData(id: number): Promise<{ name: string }> {
return fetch(`/api/users/${id}`).then(res => res.json());
}函数重载
当函数根据不同参数返回不同类型时使用:
// 重载签名
function reverse(value: string): string;
function reverse(value: number[]): number[];
// 实现签名
function reverse(value: string | number[]): string | number[] {
if (typeof value === "string") {
return value.split("").reverse().join("");
}
return value.slice().reverse();
}
// 使用
const str = reverse("hello"); // string
const arr = reverse([1, 2, 3]); // number[]复杂重载示例
interface User {
id: number;
name: string;
}
// 根据参数数量返回不同类型
function getUser(id: number): User;
function getUser(name: string): User[];
function getUser(idOrName: number | string): User | User[] {
if (typeof idOrName === "number") {
return { id: idOrName, name: "User" };
}
return [{ id: 1, name: idOrName }];
}
const user = getUser(1); // User
const users = getUser("John"); // User[]this 类型
显式 this 参数
interface Button {
label: string;
onClick(this: Button): void;
}
const button: Button = {
label: "Submit",
onClick() {
console.log(this.label); // this 被正确推断为 Button
}
};this 类型用于链式调用
class Calculator {
private value: number = 0;
add(n: number): this {
this.value += n;
return this;
}
subtract(n: number): this {
this.value -= n;
return this;
}
getResult(): number {
return this.value;
}
}
const result = new Calculator()
.add(10)
.subtract(3)
.add(5)
.getResult(); // 12泛型函数
基本泛型函数
function identity<T>(value: T): T {
return value;
}
// 显式指定类型
identity<string>("hello"); // string
identity<number>(42); // number
// 类型推断
identity("hello"); // 推断为 string
identity(42); // 推断为 number多个类型参数
function pair<K, V>(key: K, value: V): [K, V] {
return [key, value];
}
const p = pair("name", "Alice"); // [string, string]
const q = pair(1, true); // [number, boolean]泛型约束
interface Lengthwise {
length: number;
}
function logLength<T extends Lengthwise>(value: T): T {
console.log(value.length);
return value;
}
logLength("hello"); // 5
logLength([1, 2, 3]); // 3
// logLength(123); // 错误:number 没有 length 属性回调函数类型
// 同步回调
function process(callback: (data: string) => void): void {
callback("processed data");
}
// 异步回调
function fetchData(callback: (error: Error | null, data?: string) => void): void {
// ...
}
// 使用泛型
function map<T, U>(arr: T[], fn: (item: T, index: number) => U): U[] {
return arr.map(fn);
}
const numbers = [1, 2, 3];
const strings = map(numbers, n => n.toString()); // string[]函数类型工具
Parameters 提取参数类型
function greet(name: string, age: number): string {
return `${name} is ${age}`;
}
type GreetParams = Parameters<typeof greet>; // [string, number]ReturnType 提取返回类型
function createUser() {
return { id: 1, name: "Alice" };
}
type User = ReturnType<typeof createUser>; // { id: number; name: string }构造函数类型
interface UserConstructor {
new (name: string, age: number): User;
}
class User {
constructor(public name: string, public age: number) {}
}
function createInstance(ctor: UserConstructor, name: string, age: number): User {
return new ctor(name, age);
}最佳实践
- 优先使用箭头函数:避免
this绑定问题 - 显式声明返回类型:提高代码可读性和类型安全
- 避免过多参数:超过 3 个参数考虑使用对象
- 合理使用重载:优先使用联合类型,复杂场景才用重载
- 泛型命名规范:
T类型、K键、V值、E元素
// 推荐:使用对象参数
interface RequestOptions {
url: string;
method: string;
headers?: Record<string, string>;
body?: unknown;
}
function request(options: RequestOptions): Promise<Response> {
// ...
}
// 不推荐:过多位置参数
function request(
url: string,
method: string,
headers?: Record<string, string>,
body?: unknown
): Promise<Response> {
// ...
}