TypeScript 函数和类
概述
函数和类是 TypeScript 中两个核心的编程概念。函数用于封装可重用的代码逻辑,类用于创建对象和实现面向对象编程。本教程将详细介绍 TypeScript 中函数和类的使用方法。
函数类型
函数声明
// 基本函数声明
function add(a: number, b: number): number {
return a + b;
}
// 使用函数
const result = add(5, 3);
console.log(result); // 8
// 带默认参数的函数
function greet(name: string, greeting: string = '你好'): string {
return `${greeting},${name}!`;
}
console.log(greet('张三')); // 你好,张三!
console.log(greet('李四', '早上好')); // 早上好,李四!
// 带可选参数的函数
function createUser(name: string, age?: number, email?: string) {
const user: any = { name };
if (age !== undefined) {
user.age = age;
}
if (email !== undefined) {
user.email = email;
}
return user;
}
const user1 = createUser('张三');
const user2 = createUser('李四', 25);
const user3 = createUser('王五', 30, 'wangwu@example.com');
函数表达式
// 函数表达式
const multiply = function(a: number, b: number): number {
return a * b;
};
// 箭头函数
const divide = (a: number, b: number): number => {
return a / b;
};
// 简化的箭头函数
const square = (x: number): number => x * x;
// 函数类型
type MathOperation = (a: number, b: number) => number;
const add: MathOperation = (a, b) => a + b;
const subtract: MathOperation = (a, b) => a - b;
// 使用函数类型
function calculate(a: number, b: number, operation: MathOperation): number {
return operation(a, b);
}
console.log(calculate(10, 5, add)); // 15
console.log(calculate(10, 5, subtract)); // 5
函数重载
// 函数重载声明
function processInput(input: string): string;
function processInput(input: number): number;
function processInput(input: boolean): boolean;
// 函数实现
function processInput(input: string | number | boolean): string | number | boolean {
if (typeof input === 'string') {
return input.toUpperCase();
} else if (typeof input === 'number') {
return input * 2;
} else {
return !input;
}
}
// 使用重载函数
console.log(processInput('hello')); // HELLO
console.log(processInput(5)); // 10
console.log(processInput(true)); // false
// 更复杂的重载示例
function createElement(tag: string): HTMLElement;
function createElement(tag: string, props: Record<string, any>): HTMLElement;
function createElement(tag: string, props: Record<string, any>, children: string[]): HTMLElement;
function createElement(tag: string, props?: Record<string, any>, children?: string[]): HTMLElement {
const element = document.createElement(tag);
if (props) {
Object.entries(props).forEach(([key, value]) => {
(element as any)[key] = value;
});
}
if (children) {
children.forEach(child => {
element.appendChild(document.createTextNode(child));
});
}
return element;
}
// 使用重载函数
const div1 = createElement('div');
const div2 = createElement('div', { id: 'myDiv', className: 'container' });
const div3 = createElement('div', { id: 'myDiv' }, ['Hello', 'World']);
泛型函数
// 基本泛型函数
function identity<T>(arg: T): T {
return arg;
}
const num = identity<number>(42);
const str = identity<string>('hello');
const bool = identity(true);
// 类型推断
const num2 = identity(42); // 推断为 number
const str2 = identity('hello'); // 推断为 string
// 多个泛型参数
function pair<T, U>(first: T, second: U): [T, U] {
return [first, second];
}
const p1 = pair(1, 'one');
const p2 = pair('hello', 42);
// 泛型约束
interface Lengthwise {
length: number;
}
function getLength<T extends Lengthwise>(arg: T): number {
return arg.length;
}
console.log(getLength('hello')); // 5
console.log(getLength([1, 2, 3])); // 3
console.log(getLength({ length: 10, value: 'test' })); // 10
// 在泛型约束中使用类型参数
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = {
name: '张三',
age: 25,
email: 'zhangsan@example.com'
};
console.log(getProperty(user, 'name')); // 张三
console.log(getProperty(user, 'age')); // 25
类的定义
基本类
// 基本类定义
class Person {
// 属性
name: string;
age: number;
// 构造函数
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// 方法
greet(): string {
return `你好,我是${this.name},今年${this.age}岁`;
}
// 方法
celebrateBirthday(): void {
this.age++;
console.log(`${this.name} 过生日了,现在 ${this.age} 岁`);
}
}
// 使用类
const person = new Person('张三', 25);
console.log(person.greet()); // 你好,我是张三,今年25岁
person.celebrateBirthday(); // 张三 过生日了,现在 26 岁
访问修饰符
class BankAccount {
// public: 公开属性(默认)
public accountNumber: string;
// private: 私有属性
private balance: number;
// protected: 受保护属性
protected owner: string;
constructor(accountNumber: string, initialBalance: number, owner: string) {
this.accountNumber = accountNumber;
this.balance = initialBalance;
this.owner = owner;
}
// 公开方法
public deposit(amount: number): void {
if (amount > 0) {
this.balance += amount;
console.log(`存入 ${amount},余额: ${this.balance}`);
}
}
// 公开方法
public withdraw(amount: number): void {
if (amount > 0 && amount <= this.balance) {
this.balance -= amount;
console.log(`取出 ${amount},余额: ${this.balance}`);
} else {
console.log('取款失败:余额不足');
}
}
// 私有方法
private validateAmount(amount: number): boolean {
return amount > 0 && amount <= this.balance;
}
// 受保护方法
protected getBalance(): number {
return this.balance;
}
}
// 使用类
const account = new BankAccount('123456', 1000, '张三');
account.deposit(500); // 存入 500,余额: 1500
account.withdraw(200); // 取出 200,余额: 1300
// account.balance = 0; // 错误:balance 是私有的
// account.validateAmount(100); // 错误:validateAmount 是私有的
只读属性
class Product {
readonly id: number;
name: string;
price: number;
readonly createdAt: Date;
constructor(id: number, name: string, price: number) {
this.id = id;
this.name = name;
this.price = price;
this.createdAt = new Date();
}
updatePrice(newPrice: number): void {
this.price = newPrice;
}
// 只读方法
getInfo(): string {
return `产品: ${this.name}, 价格: ${this.price}`;
}
}
const product = new Product(1, '商品A', 99.99);
console.log(product.getInfo()); // 产品: 商品A, 价格: 99.99
product.updatePrice(89.99);
console.log(product.getInfo()); // 产品: 商品A, 价格: 89.99
// product.id = 2; // 错误:id 是只读的
// product.createdAt = new Date(); // 错误:createdAt 是只读的
参数属性
// 使用参数属性简化类定义
class Employee {
// 参数属性:自动创建属性并赋值
constructor(
public id: number,
public name: string,
public department: string,
private salary: number
) {}
getSalary(): number {
return this.salary;
}
giveRaise(percentage: number): void {
this.salary *= (1 + percentage / 100);
console.log(`${this.name} 的工资增加了 ${percentage}%`);
}
getInfo(): string {
return `员工: ${this.name}, 部门: ${this.department}`;
}
}
// 使用类
const employee = new Employee(1, '张三', '技术部', 5000);
console.log(employee.getInfo()); // 员工: 张三, 部门: 技术部
console.log(employee.getSalary()); // 5000
employee.giveRaise(10); // 张三 的工资增加了 10%
console.log(employee.getSalary()); // 5500
继承和多态
类继承
// 基类
class Animal {
protected name: string;
protected age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public makeSound(): void {
console.log(`${this.name} 发出声音`);
}
public eat(): void {
console.log(`${this.name} 正在吃东西`);
}
public sleep(): void {
console.log(`${this.name} 正在睡觉`);
}
}
// 派生类
class Dog extends Animal {
private breed: string;
constructor(name: string, age: number, breed: string) {
super(name, age); // 调用父类构造函数
this.breed = breed;
}
// 重写方法
public makeSound(): void {
console.log(`${this.name} 汪汪叫`);
}
// 新增方法
public fetch(): void {
console.log(`${this.name} 去捡球`);
}
public getInfo(): string {
return `狗: ${this.name}, 品种: ${this.breed}, 年龄: ${this.age}`;
}
}
// 另一个派生类
class Cat extends Animal {
private color: string;
constructor(name: string, age: number, color: string) {
super(name, age);
this.color = color;
}
// 重写方法
public makeSound(): void {
console.log(`${this.name} 喵喵叫`);
}
// 新增方法
public climb(): void {
console.log(`${this.name} 爬树`);
}
public getInfo(): string {
return `猫: ${this.name}, 颜色: ${this.color}, 年龄: ${this.age}`;
}
}
// 使用继承
const dog = new Dog('旺财', 3, '金毛');
const cat = new Cat('咪咪', 2, '白色');
dog.makeSound(); // 旺财 汪汪叫
dog.eat(); // 旺财 正在吃东西
dog.fetch(); // 旺财 去捡球
cat.makeSound(); // 咪咪 喵喵叫
cat.eat(); // 咪咪 正在吃东西
cat.climb(); // 咪咪 爬树
多态
// 使用多态
function animalAction(animal: Animal): void {
console.log(`--- ${animal['name']} 的动作 ---`);
animal.makeSound();
animal.eat();
animal.sleep();
}
// 多态调用
animalAction(dog);
// --- 旺财 的动作 ---
// 旺财 汪汪叫
// 旺财 正在吃东西
// 旺财 正在睡觉
animalAction(cat);
// --- 咪咪 的动作 ---
// 咪咪 喵喵叫
// 咪咪 正在吃东西
// 咪咪 正在睡觉
// 类型守卫
function isDog(animal: Animal): animal is Dog {
return animal instanceof Dog;
}
function animalSpecificAction(animal: Animal): void {
if (isDog(animal)) {
animal.fetch();
} else if (animal instanceof Cat) {
animal.climb();
}
}
animalSpecificAction(dog); // 旺财 去捡球
animalSpecificAction(cat); // 咪咪 爬树
抽象类
// 抽象类
abstract class Shape {
protected color: string;
constructor(color: string) {
this.color = color;
}
// 抽象方法:必须在派生类中实现
abstract calculateArea(): number;
// 具体方法
public getColor(): string {
return this.color;
}
// 具体方法
public setColor(color: string): void {
this.color = color;
}
}
// 派生类实现抽象方法
class Circle extends Shape {
private radius: number;
constructor(color: string, radius: number) {
super(color);
this.radius = radius;
}
public calculateArea(): number {
return Math.PI * this.radius * this.radius;
}
public getRadius(): number {
return this.radius;
}
}
class Rectangle extends Shape {
private width: number;
private height: number;
constructor(color: string, width: number, height: number) {
super(color);
this.width = width;
this.height = height;
}
public calculateArea(): number {
return this.width * this.height;
}
public getDimensions(): { width: number; height: number } {
return { width: this.width, height: this.height };
}
}
// 使用抽象类
const circle = new Circle('红色', 5);
const rectangle = new Rectangle('蓝色', 4, 6);
console.log(`圆形面积: ${circle.calculateArea().toFixed(2)}`); // 圆形面积: 78.54
console.log(`矩形面积: ${rectangle.calculateArea()}`); // 矩形面积: 24
// 不能直接实例化抽象类
// const shape = new Shape('绿色'); // 错误
接口实现
实现接口
// 定义接口
interface Printable {
print(): void;
}
interface Serializable {
serialize(): string;
deserialize(data: string): void;
}
// 类实现多个接口
class Document implements Printable, Serializable {
private content: string;
constructor(content: string) {
this.content = content;
}
public print(): void {
console.log(`文档内容: ${this.content}`);
}
public serialize(): string {
return JSON.stringify({ content: this.content });
}
public deserialize(data: string): void {
const parsed = JSON.parse(data);
this.content = parsed.content;
}
public getContent(): string {
return this.content;
}
public setContent(content: string): void {
this.content = content;
}
}
// 使用实现接口的类
const document = new Document('这是一份重要文档');
document.print(); // 文档内容: 这份重要文档
const serialized = document.serialize();
console.log(`序列化数据: ${serialized}`); // 序列化数据: {"content":"这是一份重要文档"}
const newDocument = new Document('');
newDocument.deserialize(serialized);
console.log(`反序列化内容: ${newDocument.getContent()}`); // 反序列化内容: 这份重要文档
接口继承
// 基础接口
interface Animal {
name: string;
age: number;
makeSound(): void;
}
// 继承接口
interface Pet extends Animal {
owner: string;
play(): void;
}
// 实现继承的接口
class Dog implements Pet {
public name: string;
public age: number;
public owner: string;
constructor(name: string, age: number, owner: string) {
this.name = name;
this.age = age;
this.owner = owner;
}
public makeSound(): void {
console.log(`${this.name} 汪汪叫`);
}
public play(): void {
console.log(`${this.name} 和 ${this.owner} 玩耍`);
}
}
// 使用
const petDog = new Dog('旺财', 3, '张三');
petDog.makeSound(); // 旺财 汪汪叫
petDog.play(); // 旺财 和 张三 玩耍
高级特性
静态成员
class MathUtils {
// 静态属性
static PI: number = 3.14159;
// 静态方法
static circleArea(radius: number): number {
return this.PI * radius * radius;
}
static circleCircumference(radius: number): number {
return 2 * this.PI * radius;
}
// 实例方法
add(a: number, b: number): number {
return a + b;
}
}
// 使用静态成员
console.log(`圆周率: ${MathUtils.PI}`); // 圆周率: 3.14159
console.log(`圆面积: ${MathUtils.circleArea(5).toFixed(2)}`); // 圆面积: 78.54
console.log(`圆周长: ${MathUtils.circleCircumference(5).toFixed(2)}`); // 圆周长: 31.42
// 使用实例方法
const utils = new MathUtils();
console.log(`加法: ${utils.add(3, 5)}`); // 加法: 8
Getter 和 Setter
class Temperature {
private _celsius: number;
constructor(celsius: number) {
this._celsius = celsius;
}
// Getter
get celsius(): number {
return this._celsius;
}
// Setter
set celsius(value: number) {
if (value >= -273.15) {
this._celsius = value;
} else {
console.log('温度不能低于绝对零度');
}
}
// Getter
get fahrenheit(): number {
return (this._celsius * 9 / 5) + 32;
}
// Setter
set fahrenheit(value: number) {
this._celsius = (value - 32) * 5 / 9;
}
// Getter
get kelvin(): number {
return this._celsius + 273.15;
}
// Setter
set kelvin(value: number) {
this._celsius = value - 273.15;
}
}
// 使用 Getter 和 Setter
const temp = new Temperature(25);
console.log(`摄氏度: ${temp.celsius}`); // 摄氏度: 25
console.log(`华氏度: ${temp.fahrenheit.toFixed(2)}`); // 华氏度: 77.00
console.log(`开尔文: ${temp.kelvin.toFixed(2)}`); // 开尔文: 298.15
temp.fahrenheit = 100;
console.log(`摄氏度: ${temp.celsius.toFixed(2)}`); // 摄氏度: 37.78
temp.celsius = -300; // 温度不能低于绝对零度
类表达式
// 类表达式
const MyClass = class {
private value: number;
constructor(value: number) {
this.value = value;
}
public getValue(): number {
return this.value;
}
public setValue(value: number): void {
this.value = value;
}
};
// 使用类表达式
const instance = new MyClass(42);
console.log(instance.getValue()); // 42
// 泛型类表达式
const GenericClass = class<T> {
private value: T;
constructor(value: T) {
this.value = value;
}
public getValue(): T {
return this.value;
}
public setValue(value: T): void {
this.value = value;
}
};
const stringInstance = new GenericClass<string>('hello');
console.log(stringInstance.getValue()); // hello
const numberInstance = new GenericClass<number>(42);
console.log(numberInstance.getValue()); // 42
实际应用示例
用户管理系统
// 用户接口
interface IUser {
id: number;
name: string;
email: string;
role: 'admin' | 'user' | 'guest';
createdAt: Date;
}
// 用户类
class User implements IUser {
public id: number;
public name: string;
public email: string;
public role: 'admin' | 'user' | 'guest';
public createdAt: Date;
constructor(id: number, name: string, email: string, role: 'admin' | 'user' | 'guest') {
this.id = id;
this.name = name;
this.email = email;
this.role = role;
this.createdAt = new Date();
}
public hasPermission(permission: string): boolean {
const permissions: Record<string, string[]> = {
admin: ['create', 'read', 'update', 'delete'],
user: ['read', 'update'],
guest: ['read']
};
return permissions[this.role].includes(permission);
}
public getInfo(): string {
return `用户: ${this.name} (${this.email}), 角色: ${this.role}`;
}
}
// 用户管理类
class UserManager {
private users: Map<number, User> = new Map();
private nextId: number = 1;
public createUser(name: string, email: string, role: 'admin' | 'user' | 'guest'): User {
const user = new User(this.nextId++, name, email, role);
this.users.set(user.id, user);
return user;
}
public getUser(id: number): User | undefined {
return this.users.get(id);
}
public updateUser(id: number, updates: Partial<Pick<User, 'name' | 'email' | 'role'>>): boolean {
const user = this.users.get(id);
if (!user) {
return false;
}
if (updates.name) {
user.name = updates.name;
}
if (updates.email) {
user.email = updates.email;
}
if (updates.role) {
user.role = updates.role;
}
return true;
}
public deleteUser(id: number): boolean {
return this.users.delete(id);
}
public listUsers(): User[] {
return Array.from(this.users.values());
}
public findUsersByRole(role: 'admin' | 'user' | 'guest'): User[] {
return this.listUsers().filter(user => user.role === role);
}
}
// 使用用户管理系统
const userManager = new UserManager();
// 创建用户
const admin = userManager.createUser('张三', 'zhangsan@example.com', 'admin');
const user1 = userManager.createUser('李四', 'lisi@example.com', 'user');
const user2 = userManager.createUser('王五', 'wangwu@example.com', 'user');
const guest = userManager.createUser('赵六', 'zhaoliu@example.com', 'guest');
// 检查权限
console.log(`${admin.name} 可以删除: ${admin.hasPermission('delete')}`); // 张三 可以删除: true
console.log(`${user1.name} 可以删除: ${user1.hasPermission('delete')}`); // 李四 可以删除: false
// 列出所有用户
console.log('所有用户:');
userManager.listUsers().forEach(user => {
console.log(user.getInfo());
});
// 按角色查找用户
console.log('普通用户:');
userManager.findUsersByRole('user').forEach(user => {
console.log(user.getInfo());
});
// 更新用户
userManager.updateUser(user1.id, { name: '李四(更新)' });
console.log(userManager.getUser(user1.id)?.getInfo()); // 用户: 李四(更新) (lisi@example.com), 角色: user
// 删除用户
userManager.deleteUser(guest.id);
console.log('删除后的用户列表:');
userManager.listUsers().forEach(user => {
console.log(user.getInfo());
});
数据库连接池
// 数据库连接接口
interface DatabaseConnection {
connect(): Promise<void>;
disconnect(): Promise<void>;
query(sql: string, params?: any[]): Promise<any[]>;
isConnected(): boolean;
}
// 数据库连接实现
class MySQLConnection implements DatabaseConnection {
private connected: boolean = false;
private connectionId: string;
constructor(connectionId: string) {
this.connectionId = connectionId;
}
public async connect(): Promise<void> {
console.log(`连接 ${this.connectionId} 到 MySQL 数据库...`);
// 模拟连接延迟
await new Promise(resolve => setTimeout(resolve, 100));
this.connected = true;
console.log(`连接 ${this.connectionId} 已建立`);
}
public async disconnect(): Promise<void> {
console.log(`断开连接 ${this.connectionId}...`);
// 模拟断开延迟
await new Promise(resolve => setTimeout(resolve, 50));
this.connected = false;
console.log(`连接 ${this.connectionId} 已断开`);
}
public async query(sql: string, params?: any[]): Promise<any[]> {
if (!this.connected) {
throw new Error('连接未建立');
}
console.log(`执行查询: ${sql}`);
// 模拟查询延迟
await new Promise(resolve => setTimeout(resolve, 100));
// 返回模拟数据
return [
{ id: 1, name: '张三' },
{ id: 2, name: '李四' }
];
}
public isConnected(): boolean {
return this.connected;
}
public getConnectionId(): string {
return this.connectionId;
}
}
// 连接池类
class ConnectionPool {
private pool: DatabaseConnection[] = [];
private maxConnections: number;
private minConnections: number;
private availableConnections: DatabaseConnection[] = [];
private busyConnections: Set<DatabaseConnection> = new Set();
constructor(maxConnections: number, minConnections: number = 1) {
this.maxConnections = maxConnections;
this.minConnections = minConnections;
}
public async initialize(): Promise<void> {
console.log(`初始化连接池,最小连接数: ${this.minConnections}`);
for (let i = 0; i < this.minConnections; i++) {
const connection = new MySQLConnection(`conn-${i + 1}`);
await connection.connect();
this.pool.push(connection);
this.availableConnections.push(connection);
}
console.log(`连接池初始化完成,当前连接数: ${this.pool.length}`);
}
public async getConnection(): Promise<DatabaseConnection> {
// 如果有可用连接,直接返回
if (this.availableConnections.length > 0) {
const connection = this.availableConnections.pop()!;
this.busyConnections.add(connection);
console.log(`获取连接: ${connection['getConnectionId']()}`);
return connection;
}
// 如果没有可用连接且未达到最大连接数,创建新连接
if (this.pool.length < this.maxConnections) {
const connection = new MySQLConnection(`conn-${this.pool.length + 1}`);
await connection.connect();
this.pool.push(connection);
this.busyConnections.add(connection);
console.log(`创建新连接: ${connection['getConnectionId']()}`);
return connection;
}
// 等待可用连接
console.log('等待可用连接...');
await new Promise(resolve => setTimeout(resolve, 100));
return this.getConnection();
}
public releaseConnection(connection: DatabaseConnection): void {
if (this.busyConnections.has(connection)) {
this.busyConnections.delete(connection);
this.availableConnections.push(connection);
console.log(`释放连接: ${connection['getConnectionId']()}`);
}
}
public async close(): Promise<void> {
console.log('关闭连接池...');
const closePromises = this.pool.map(async connection => {
if (connection.isConnected()) {
await connection.disconnect();
}
});
await Promise.all(closePromises);
this.pool = [];
this.availableConnections = [];
this.busyConnections.clear();
console.log('连接池已关闭');
}
public getPoolStatus(): {
total: number;
available: number;
busy: number;
} {
return {
total: this.pool.length,
available: this.availableConnections.length,
busy: this.busyConnections.size
};
}
}
// 使用连接池
async function useConnectionPool() {
const pool = new ConnectionPool(5, 2);
// 初始化连接池
await pool.initialize();
console.log('连接池状态:', pool.getPoolStatus());
// 获取连接并执行查询
const conn1 = await pool.getConnection();
const result1 = await conn1.query('SELECT * FROM users');
console.log('查询结果:', result1);
pool.releaseConnection(conn1);
const conn2 = await pool.getConnection();
const result2 = await conn2.query('SELECT * FROM products');
console.log('查询结果:', result2);
pool.releaseConnection(conn2);
console.log('连接池状态:', pool.getPoolStatus());
// 关闭连接池
await pool.close();
}
useConnectionPool();
总结
本教程详细介绍了 TypeScript 函数和类:
-
函数类型:
- 函数声明
- 函数表达式
- 函数重载
- 泛型函数
-
类的定义:
- 基本类
- 访问修饰符
- 只读属性
- 参数属性
-
继承和多态:
- 类继承
- 方法重写
- 多态
- 抽象类
-
接口实现:
- 实现接口
- 接口继承
- 多接口实现
-
高级特性:
- 静态成员
- Getter 和 Setter
- 类表达式
-
实际应用:
- 用户管理系统
- 数据库连接池
函数和类是 TypeScript 面向对象编程的基础,掌握它们对于构建复杂的应用程序至关重要。
下一步
在下一教程中,我们将学习 TypeScript 泛型,包括:
-
泛型基础
-
泛型约束
-
泛型接口
-
泛型类
-
条件类型
-
映射类型
继续学习 TypeScript,掌握这门强大语言的更多知识!

