面试题答案
一键面试1. 使用import
和export
合理组织TypeScript代码提高可维护性和复用性
- 按功能拆分模块:将不同功能的代码分别放在不同文件中,通过
export
导出需要对外暴露的接口、类、函数等。例如,在一个电商项目中,将用户相关操作(登录、注册等)放在user.ts
文件中:
// user.ts
export function login(username: string, password: string): boolean {
// 登录逻辑
return true;
}
export function register(username: string, password: string): boolean {
// 注册逻辑
return true;
}
在其他文件中通过import
引入:
// main.ts
import { login, register } from './user';
// 使用login和register函数
- 使用命名空间
namespace
(在某些场景下):当模块内功能有更细粒度的划分时,可使用命名空间。例如在图形绘制库中:
// graphics.ts
export namespace Shapes {
export class Circle {
constructor(public radius: number) {}
area() {
return Math.PI * this.radius * this.radius;
}
}
export class Rectangle {
constructor(public width: number, public height: number) {}
area() {
return this.width * this.height;
}
}
}
引入使用:
// app.ts
import { Shapes } from './graphics';
const circle = new Shapes.Circle(5);
const rect = new Shapes.Rectangle(4, 5);
- 默认导出和命名导出结合:对于每个模块的主要导出内容,可使用默认导出,次要的使用命名导出。如在一个工具模块中:
// utils.ts
// 默认导出一个通用的格式化函数
export default function formatDate(date: Date): string {
return date.toISOString();
}
// 命名导出一个计算两个数之和的函数
export function add(a: number, b: number): number {
return a + b;
}
引入使用:
// main.ts
import formatDate, { add } from './utils';
const dateStr = formatDate(new Date());
const sum = add(3, 5);
2. 处理复杂模块依赖关系的经验和技巧
- 绘制依赖关系图:在项目初期,通过绘制模块依赖关系图,清晰了解各模块之间的依赖情况。例如在一个大型微服务项目中,各个服务模块之间存在调用关系,通过图形化展示能直观看到哪些模块依赖哪些其他模块,有助于发现不合理的依赖,提前优化。
- 使用
@types
定义外部库类型:当项目依赖第三方库时,使用@types
来定义类型,确保类型安全,避免因类型不匹配导致的难以调试的错误。比如使用lodash
库,安装@types/lodash
,在代码中引入:
import _ from 'lodash';
const result = _.map([1, 2, 3], (num) => num * 2);
- 控制依赖深度:尽量减少模块之间的依赖层级,避免过度复杂的嵌套依赖。如果一个模块A依赖B,B依赖C,C又依赖D,这种过深的依赖会使维护成本大增。可通过重构,将一些通用逻辑提取到更高层次的模块,减少依赖链。例如在一个多层级的UI组件库项目中,将一些底层的样式工具函数提取到公共模块,减少组件之间因样式工具依赖产生的复杂层级依赖。
- 懒加载模块:对于一些不常用或资源消耗大的模块,采用懒加载的方式。在Web应用中,使用动态
import()
语法实现懒加载。例如,在一个大型单页应用中,某个报表生成功能不常用,可这样实现懒加载:
// 在需要时加载报表模块
async function generateReport() {
const reportModule = await import('./report');
reportModule.generate();
}