04.TypeScript 函数类型
1. 函数类型
在 TypeScript 中,函数也是一种数据类型。我们可以为函数定义类型,包括参数类型和返回值类型。
typescript
function add(x: number, y: number): number {
return x + y;
}
// 函数调用示例
// 调用 add 函数传入参数 2 和 3,返回它们的和 5
console.log(add(2, 3)); // 输出: 5
2. 函数接口
我们也可以使用接口来定义函数类型。
typescript
interface Add {
(x: number, y: number): number;
}
let myAdd: Add = function(x: number, y: number): number {
return x + y;
};
// 函数调用示例
// 通过接口定义函数类型,实现相同的功能,调用 myAdd(2, 3) 返回 5
console.log(myAdd(2, 3)); // 输出: 5
3. 函数重载
TypeScript 支持函数重载,即同一个函数名可以有多种参数类型和返回值类型的组合。
typescript
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else {
return x.split('').reverse().join('');
}
}
// 函数调用示例
// 调用 reverse 函数处理数字 12345,将其转换为字符串反转后再转回数字,得到 54321
console.log(reverse(12345)); // 输出: 54321
// 调用 reverse 函数处理字符串 "hello",返回反转后的字符串 "olleh"
console.log(reverse("hello")); // 输出: "olleh"
4. 泛型函数
泛型函数允许我们编写可以适用于多种类型的函数。
typescript
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("myString");
// 或者让编译器自动推断类型
let output2 = identity("myString");
// 输出示例
// 显式指定泛型类型为 string,传入 "myString" 并返回相同值
console.log(output); // 输出: "myString"
// 利用类型推断,编译器自动识别类型为 string,传入 "myString" 并返回相同值
console.log(output2); // 输出: "myString"
5. 可选参数和默认参数
TypeScript 支持可选参数和默认参数。
typescript
function buildName(firstName: string, lastName?: string) {
if (lastName) return firstName + " " + lastName;
else return firstName;
}
function buildNameWithDefault(firstName: string, lastName = "Smith") {
return firstName + " " + lastName;
}
// 函数调用示例
// 只传入 firstName 参数,lastName 为可选参数未传入,返回 "John"
console.log(buildName("John")); // 输出: "John"
// 传入 firstName 和 lastName 参数,返回组合后的完整名字 "John Doe"
console.log(buildName("John", "Doe")); // 输出: "John Doe"
// 只传入 firstName 参数,lastName 使用默认值 "Smith",返回 "John Smith"
console.log(buildNameWithDefault("John")); // 输出: "John Smith"
// 传入 firstName 和 lastName 参数,覆盖默认值,返回 "John Doe"
console.log(buildNameWithDefault("John", "Doe")); // 输出: "John Doe"
6. 剩余参数
TypeScript 支持使用 ...
语法来定义剩余参数。
typescript
function buildNameWithRest(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
// 函数调用示例
// 使用剩余参数语法,将 "Doe" 和 "Smith" 收集到 restOfName 数组中,然后通过 join 方法连接成字符串
console.log(buildNameWithRest("John", "Doe", "Smith")); // 输出: "John Doe Smith"

7. this 和箭头函数
TypeScript 允许我们指定函数中 this
的类型。
typescript
class MyClass {
name = "MyClass";
getName(this: MyClass) {
return this.name;
}
}
let c = new MyClass();
let g = c.getName();
// 在 MyClass 中定义 getName 方法并指定 this 类型为 MyClass,调用时返回实例的 name 属性
console.log(g); // 输出: "MyClass"
// 箭头函数会捕获其所在上下文的 this 值
class MyClassArrow {
name = "MyClassArrow";
getName = () => {
return this.name;
}
}
let c2 = new MyClassArrow();
let g2 = c2.getName();
// 使用箭头函数定义 getName,它会自动捕获定义时的 this 上下文,调用时同样返回实例的 name 属性
console.log(g2); // 输出: "MyClassArrow"
8. 函数重载与 this 类型
在类中定义方法时,可以使用 this 类型进行重载。
typescript
class MyClass1 {
name = "MyClass1";
getName(this: void): string;
getName(this: MyClass1): string;
getName(this: void | MyClass1) {
if (this instanceof MyClass1) {
return this.name;
} else {
return "This is not an instance method";
}
}
}
// 函数调用示例
let c = new MyClass1();
// 直接通过实例调用 getName 方法,匹配第一个重载签名,返回实例的 name 属性
console.log(c.getName()); // 输出: "MyClass1"
let fn = c.getName;
// 将方法赋值给变量后调用,此时 this 为 void,匹配第二个重载签名,返回字符串
console.log(fn()); // 输出: "This is not an instance method"

9. 总结
- 函数类型:如何为函数定义参数类型和返回值类型,确保函数调用时的类型安全;
- 函数接口:使用接口来定义函数类型,提供更清晰的类型约束;
- 函数重载:同一个函数名支持多种参数类型和返回值类型的组合,增强函数的灵活性;
- 泛型函数:编写可以适用于多种类型的函数,提高代码复用性;
- 可选参数和默认参数:处理函数参数的不同情况,使函数调用更加灵活;
- 剩余参数 :使用
...
语法处理不定数量的参数,方便处理变长参数列表; - this 和箭头函数 :指定函数中
this
的类型,以及箭头函数的特性,确保正确的上下文绑定; - 函数重载与 this 类型:在类中定义方法时使用 this 类型进行重载,处理方法调用时的不同上下文。