TypeScript函数知识大全
编程小白也能理解的TypeScript函数核心知识点
函数定义方式
1. 函数声明
最基础的定义函数方式:
function greet(name: string): string {
return `你好, ${name}!`;
}
return `你好, ${name}!`;
}
2. 函数表达式
将函数赋值给变量:
const add = function(a: number, b: number): number {
return a + b;
};
return a + b;
};
3. 箭头函数
ES6引入的简洁语法:
const multiply = (a: number, b: number): number => a * b;
温馨提示: 箭头函数没有自己的this绑定,非常适合在回调函数中使用。
参数类型
1. 必需参数
调用函数时必须提供的参数:
function sayHello(name: string) { … }
2. 可选参数
在参数名后加?标记,表示可不传:
function buildName(firstName: string, lastName?: string) {
if (lastName) return `${firstName} ${lastName}`;
return firstName;
}
if (lastName) return `${firstName} ${lastName}`;
return firstName;
}
3. 默认参数
没有传值时使用默认值:
function discount(price: number, rate: number = 0.8) {
return price * rate;
}
return price * rate;
}
4. 剩余参数
收集多个参数到一个数组中:
function sum(…numbers: number[]): number {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
return numbers.reduce((acc, curr) => acc + curr, 0);
}
重要提示: 可选参数和默认参数不能出现在必需参数之前。
函数类型
1. 函数类型表达式
描述函数本身的类型:
type MathFunc = (x: number, y: number) => number;
const add: MathFunc = (a, b) => a + b;
const subtract: MathFunc = (a, b) => a – b;
const add: MathFunc = (a, b) => a + b;
const subtract: MathFunc = (a, b) => a – b;
2. 调用签名
在对象类型中定义函数:
type DescribableFunction = {
description: string;
(arg: number): boolean;
};
description: string;
(arg: number): boolean;
};
3. 构造签名
定义构造函数类型:
interface ClockConstructor {
new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
tick(): void;
}
new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
tick(): void;
}
函数重载
让一个函数接受不同类型或数量的参数,实现多种功能:
// 重载签名
function createDate(timestamp: number): Date;
function createDate(year: number, month: number, day: number): Date;
// 实现签名
function createDate(overload1: number, overload2?: number, overload3?: number): Date {
if (overload2 !== undefined && overload3 !== undefined) {
return new Date(overload1, overload2, overload3);
} else {
return new Date(overload1);
}
}
function createDate(timestamp: number): Date;
function createDate(year: number, month: number, day: number): Date;
// 实现签名
function createDate(overload1: number, overload2?: number, overload3?: number): Date {
if (overload2 !== undefined && overload3 !== undefined) {
return new Date(overload1, overload2, overload3);
} else {
return new Date(overload1);
}
}
注意: 实现签名必须兼容所有重载签名,且不可直接调用。
泛型函数
创建可处理多种类型的函数,提高代码复用性:
function identity<T>(arg: T): T {
return arg;
}
// 使用方式
let output1 = identity<string>(“hello”);
let output2 = identity(42); // 类型推断
return arg;
}
// 使用方式
let output1 = identity<string>(“hello”);
let output2 = identity(42); // 类型推断
泛型约束
限制泛型参数的类型范围:
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}
应用场景: 当你需要处理多种数据类型但逻辑相同时,泛型是最佳选择。
this与上下文
1. this参数
指定函数内this的类型:
interface User {
id: number;
name: string;
}
function greet(this: User) {
return `Hello, ${this.name}`;
}
const user: User = { id: 1, name: “张三” };
greet.call(user); // 正确
id: number;
name: string;
}
function greet(this: User) {
return `Hello, ${this.name}`;
}
const user: User = { id: 1, name: “张三” };
greet.call(user); // 正确
2. 箭头函数的this
箭头函数没有自己的this,它继承自外层作用域:
const counter = {
count: 0,
increment: function() {
setTimeout(() => {
this.count++; // 这里的this指向counter
}, 1000);
}
};
count: 0,
increment: function() {
setTimeout(() => {
this.count++; // 这里的this指向counter
}, 1000);
}
};
经验法则: 需要访问对象属性时使用普通函数,需要保留this上下文时使用箭头函数。
void与never
1. void类型
表示函数没有返回值:
function logMessage(message: string): void {
console.log(message);
}
console.log(message);
}
2. never类型
表示函数永远不会返回(如抛出错误或死循环):
function throwError(message: string): never {
throw new Error(message);
}
function infiniteLoop(): never {
while (true) { … }
}
throw new Error(message);
}
function infiniteLoop(): never {
while (true) { … }
}
区别: void表示函数正常执行但没有返回值,never表示函数根本不会返回。
函数类型兼容
1. 参数数量兼容
目标函数的参数可以少于源函数:
let func1 = (a: number) => 0;
let func2 = (a: number, b: string) => 0;
func2 = func1; // 正确
func1 = func2; // 错误
let func2 = (a: number, b: string) => 0;
func2 = func1; // 正确
func1 = func2; // 错误
2. 参数类型兼容
参数类型必须兼容:
let func3 = (a: number) => 0;
let func4 = (b: string) => 0;
func3 = func4; // 错误,类型不兼容
let func4 = (b: string) => 0;
func3 = func4; // 错误,类型不兼容
3. 返回值类型兼容
目标函数返回值必须是源函数返回值的子类型:
let func5 = () => ({ name: “Alice” });
let func6 = () => ({ name: “Alice”, location: “Seattle” });
func5 = func6; // 正确
func6 = func5; // 错误
let func6 = () => ({ name: “Alice”, location: “Seattle” });
func5 = func6; // 正确
func6 = func5; // 错误
TypeScript函数要点总结
TypeScript为JavaScript函数添加了强大的类型系统支持,包括:
- ✔ 明确的参数类型和返回值类型
- ✔ 可选参数、默认参数和剩余参数
- ✔ 函数重载支持多种调用方式
- ✔ 泛型函数提供类型灵活性
- ✔ 安全的this上下文管理
- ✔ void和never类型明确函数行为
掌握这些知识点,你将能编写更健壮、可维护的TypeScript代码!