1. TypeScript函数基础概念解析
TypeScript作为JavaScript的超集,在函数定义和使用上既保留了JavaScript的灵活性,又通过类型系统增强了代码的可靠性。我们先从最基础的函数定义开始:
1.1 函数声明与表达式
TypeScript支持两种基本函数定义方式:
typescript复制// 函数声明
function greet(name: string): string {
return `Hello, ${name}!`;
}
// 函数表达式
const greet = function(name: string): string {
return `Hello, ${name}!`;
};
这两种方式的主要区别在于提升(hoisting)行为:函数声明会被提升到作用域顶部,而函数表达式则遵循变量提升规则。
提示:在团队协作中,建议统一使用函数表达式,可以避免意外的提升行为导致的逻辑错误。
1.2 箭头函数
ES6引入的箭头函数在TypeScript中同样适用,并且能更好地处理this绑定问题:
typescript复制const greet = (name: string): string => `Hello, ${name}!`;
箭头函数特别适合用在回调函数中,例如数组方法:
typescript复制const numbers = [1, 2, 3];
const doubled = numbers.map((n: number) => n * 2);
1.3 函数类型注解
TypeScript强大的类型系统允许我们为函数本身添加类型注解:
typescript复制type GreetFunction = (name: string) => string;
const greet: GreetFunction = (name) => `Hello, ${name}!`;
这种类型定义方式在定义回调函数类型或高阶函数时特别有用。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 函数参数详解
2.1 可选参数与默认参数
TypeScript允许我们定义可选参数和默认参数:
typescript复制function createUser(
name: string,
age?: number, // 可选参数
role: string = 'user' // 默认参数
) {
// ...
}
注意:可选参数必须位于必选参数之后,默认参数则没有这个限制,但最佳实践还是放在参数列表末尾。
2.2 剩余参数
处理不定数量参数时,可以使用剩余参数语法:
typescript复制function sum(...numbers: number[]): number {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
剩余参数会被收集到一个数组中,这在创建工具函数时非常实用。
2.3 参数解构
结合ES6的解构语法,TypeScript可以优雅地处理复杂参数:
typescript复制function drawPoint({ x, y }: { x: number; y: number }) {
console.log(`Drawing at (${x}, ${y})`);
}
这种方式在React组件props的处理中特别常见。
3. 函数返回值类型
3.1 显式返回类型
虽然TypeScript可以推断简单函数的返回类型,但显式声明是个好习惯:
typescript复制function add(a: number, b: number): number {
return a + b;
}
3.2 void与never
对于不返回值的函数,应该使用void类型:
typescript复制function logMessage(message: string): void {
console.log(message);
}
对于永远不会正常返回的函数(如抛出错误或无限循环),使用never类型:
typescript复制function throwError(message: string): never {
throw new Error(message);
}
3.3 联合返回类型
函数可能返回多种类型时,可以使用联合类型:
typescript复制function parseInput(input: string): number | string {
const parsed = Number(input);
return isNaN(parsed) ? input : parsed;
}
4. 高级函数特性
4.1 函数重载
TypeScript支持函数重载,允许一个函数接受不同类型参数并返回不同类型:
typescript复制function makeDate(timestamp: number): Date;
function makeDate(m: number, d: number, y: number): Date;
function makeDate(mOrTimestamp: number, d?: number, y?: number): Date {
if (d !== undefined && y !== undefined) {
return new Date(y, mOrTimestamp, d);
} else {
return new Date(mOrTimestamp);
}
}
提示:函数重载的实现签名通常更宽松,需要开发者自行处理类型检查。
4.2 泛型函数
泛型使函数能够处理多种类型而不失去类型安全:
typescript复制function identity<T>(arg: T): T {
return arg;
}
// 使用
const output = identity<string>("hello");
const output2 = identity(42); // 类型推断
泛型在创建工具函数库时特别有用,如数组处理、数据转换等场景。
4.3 高阶函数
高阶函数是指接受函数作为参数或返回函数的函数:
typescript复制function filter<T>(arr: T[], predicate: (item: T) => boolean): T[] {
return arr.filter(predicate);
}
// 使用
const numbers = [1, 2, 3, 4, 5];
const evens = filter(numbers, n => n % 2 === 0);
5. 函数最佳实践与常见问题
5.1 VSCode中的函数跳转
在VSCode中,可以通过以下方式提高函数定义的跳转体验:
- 确保安装了TypeScript插件
- 使用
Ctrl+Click(Windows)或Cmd+Click(Mac)跳转到定义 - 对于无法跳转的情况,检查
tsconfig.json配置是否正确
5.2 函数组织技巧
- 将相关函数分组到模块/命名空间中
- 使用JSDoc注释说明函数用途和参数
- 避免过长的函数,遵循单一职责原则
- 对于复杂逻辑,考虑使用策略模式替代条件分支
5.3 常见错误处理
- 参数类型不匹配:确保调用时传递的参数类型与声明一致
- 返回值类型错误:检查函数所有执行路径的返回值类型
- this绑定问题:在类方法中使用箭头函数或bind确保正确的this上下文
- 异步函数处理:async函数总是返回Promise,注意类型声明
6. 函数在React/Vue中的应用
6.1 React组件中的函数
在React函数组件中,TypeScript可以很好地约束props和事件处理函数:
typescript复制interface ButtonProps {
label: string;
onClick: (event: React.MouseEvent) => void;
}
const Button: React.FC<ButtonProps> = ({ label, onClick }) => (
<button onClick={onClick}>{label}</button>
);
6.2 Vue组合式API
Vue 3的组合式API与TypeScript配合良好:
typescript复制import { defineComponent, ref, onMounted } from 'vue';
export default defineComponent({
setup() {
const count = ref(0);
const increment = () => {
count.value++;
};
onMounted(() => {
console.log('Component mounted');
});
return { count, increment };
}
});
注意:在Vue中,表单组件确实需要在onMounted后再操作DOM,这是框架的生命周期特性决定的。
7. 函数测试与调试
7.1 单元测试中的函数
使用Jest测试TypeScript函数时,类型检查可以提前发现许多问题:
typescript复制// sum.ts
export function sum(a: number, b: number): number {
return a + b;
}
// sum.test.ts
import { sum } from './sum';
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
7.2 调试技巧
- 使用
debugger语句设置断点 - 利用VSCode的调试配置
- 对于复杂函数,添加详细的日志输出
- 使用TypeScript Playground快速验证函数行为
8. 函数性能优化
8.1 避免不必要的函数创建
在React组件中,避免在渲染函数内创建新函数:
typescript复制// 不好
function Component() {
return <button onClick={() => console.log('click')}>Click</button>;
}
// 好
function Component() {
const handleClick = useCallback(() => {
console.log('click');
}, []);
return <button onClick={handleClick}>Click</button>;
}
8.2 记忆化(Memoization)
对于计算密集型函数,可以使用记忆化技术:
typescript复制import memoize from 'lodash.memoize';
const expensiveCalculation = memoize((input: number) => {
// 复杂计算
return result;
});
9. 函数式编程实践
TypeScript支持许多函数式编程概念:
9.1 纯函数
纯函数是指没有副作用且输出只依赖于输入的函数:
typescript复制function pureAdd(a: number, b: number): number {
return a + b;
}
9.2 函数组合
将多个简单函数组合成复杂操作:
typescript复制function compose<A, B, C>(f: (b: B) => C, g: (a: A) => B): (a: A) => C {
return (a: A) => f(g(a));
}
const toUpperCase = (s: string) => s.toUpperCase();
const exclaim = (s: string) => s + '!';
const shout = compose(exclaim, toUpperCase);
console.log(shout('hello')); // 输出 "HELLO!"
10. 函数与面向对象编程
10.1 类方法
在TypeScript类中定义方法时,类型系统可以确保方法签名的正确性:
typescript复制class Calculator {
add(a: number, b: number): number {
return a + b;
}
}
10.2 静态方法
静态方法属于类本身而非实例:
typescript复制class StringUtils {
static capitalize(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1);
}
}
10.3 方法重载
类方法也支持重载:
typescript复制class Logger {
log(message: string): void;
log(message: string, level: 'info' | 'warn' | 'error'): void;
log(message: string, level?: 'info' | 'warn' | 'error') {
// 实现
}
}
11. 异步函数处理
11.1 async/await
TypeScript完全支持ES2017的async/await语法:
typescript复制async function fetchData(url: string): Promise<Data> {
const response = await fetch(url);
return response.json();
}
11.2 Promise类型
明确指定Promise的解析类型:
typescript复制function delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
11.3 错误处理
正确处理异步函数中的错误:
typescript复制async function safeFetch(url: string) {
try {
const response = await fetch(url);
return await response.json();
} catch (error) {
console.error('Fetch failed:', error);
throw error; // 或者返回默认值
}
}
12. 函数类型进阶
12.1 条件类型与函数
结合条件类型创建更灵活的函数类型:
typescript复制type FunctionReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
function foo() { return 123; }
type FooReturn = FunctionReturnType<typeof foo>; // number
12.2 映射类型与函数
使用映射类型转换函数签名:
typescript复制type Promisify<T> = {
[K in keyof T]: T[K] extends (...args: infer A) => infer R
? (...args: A) => Promise<R>
: T[K];
};
12.3 函数柯里化
实现类型安全的柯里化函数:
typescript复制function curry<T, U, V>(fn: (a: T, b: U) => V): (a: T) => (b: U) => V {
return (a: T) => (b: U) => fn(a, b);
}
const add = (a: number, b: number) => a + b;
const curriedAdd = curry(add);
const addFive = curriedAdd(5);
console.log(addFive(3)); // 8
13. 函数与类型推断
13.1 上下文类型推断
TypeScript能根据上下文推断函数类型:
typescript复制const names = ['Alice', 'Bob', 'Charlie'];
// names.map的参数类型会被自动推断为(string) => any
const lengths = names.map(name => name.length);
13.2 const断言与函数
使用const断言保护函数返回类型:
typescript复制function getConfig() {
return {
apiUrl: 'https://api.example.com',
timeout: 5000
} as const;
}
// 返回类型被推断为 { readonly apiUrl: "https://api.example.com"; readonly timeout: 5000; }
13.3 satisfies操作符
TypeScript 4.9引入的satisfies操作符可以检查类型而不改变推断结果:
typescript复制const myFunc = ((x: number) => x * 2) satisfies (x: number) => number;
14. 函数签名重载与实现
14.1 构造函数重载
类构造函数也可以重载:
typescript复制class Point {
constructor(x: number, y: number);
constructor(point: { x: number; y: number });
constructor(arg1: number | { x: number; y: number }, arg2?: number) {
// 实现
}
}
14.2 接口中的函数签名
接口可以定义多种调用签名:
typescript复制interface Overloaded {
(x: string): string;
(x: number): number;
}
const fn: Overloaded = (x: any) => x;
14.3 函数属性
函数也可以拥有属性:
typescript复制interface FuncWithProps {
(x: number): number;
description: string;
}
const fn: FuncWithProps = (x) => x * 2;
fn.description = 'Doubles the input';
15. 函数与模块系统
15.1 导出函数
TypeScript支持多种导出函数的方式:
typescript复制// 具名导出
export function greet(name: string) { /* ... */ }
// 默认导出
export default function(config: Config) { /* ... */ }
// 导出函数类型
export type GreetFunction = (name: string) => string;
15.2 动态导入函数
使用动态导入按需加载函数:
typescript复制async function loadUtils() {
const utils = await import('./utils');
utils.someFunction();
}
15.3 命名空间中的函数
对于旧代码,可以使用命名空间组织函数:
typescript复制namespace StringUtils {
export function capitalize(str: string) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
}
16. 函数与装饰器
16.1 方法装饰器
装饰器可以修改类方法行为:
typescript复制function log(target: any, key: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${key} with`, args);
return original.apply(this, args);
};
return descriptor;
}
class Calculator {
@log
add(a: number, b: number) {
return a + b;
}
}
16.2 参数装饰器
装饰器也可以用于方法参数:
typescript复制function validate(target: any, key: string, index: number) {
// 验证逻辑
}
class UserService {
create(@validate name: string) {
// ...
}
}
16.3 高阶函数与装饰器模式
使用高阶函数实现类似装饰器的功能:
typescript复制function withLogging(fn: Function) {
return (...args: any[]) => {
console.log('Arguments:', args);
return fn(...args);
};
}
const loggedAdd = withLogging((a: number, b: number) => a + b);
17. 函数与类型守卫
17.1 自定义类型守卫
创建类型谓词函数来缩小类型范围:
typescript复制function isString(value: any): value is string {
return typeof value === 'string';
}
function process(input: string | number) {
if (isString(input)) {
// 这里input被推断为string
console.log(input.toUpperCase());
} else {
// 这里input被推断为number
console.log(input.toFixed(2));
}
}
17.2 断言函数
TypeScript 3.7引入了断言函数:
typescript复制function assert(condition: any, msg?: string): asserts condition {
if (!condition) throw new Error(msg);
}
function assertIsString(val: any): asserts val is string {
if (typeof val !== 'string') throw new Error('Not a string!');
}
17.3 过滤函数中的类型守卫
在数组过滤中使用类型守卫:
typescript复制const mixedArray = [1, 'two', 3, 'four'];
// 过滤出字符串
const strings = mixedArray.filter((item): item is string => typeof item === 'string');
18. 函数与工具类型
18.1 内置工具类型
TypeScript提供了多种操作函数类型的工具类型:
typescript复制// Parameters - 获取函数参数类型
type AddParams = Parameters<(a: number, b: number) => number>; // [number, number]
// ReturnType - 获取函数返回类型
type AddReturn = ReturnType<(a: number, b: number) => number>; // number
18.2 创建自定义工具类型
基于内置类型创建更复杂的工具类型:
typescript复制type Asyncify<T extends (...args: any[]) => any> =
(...args: Parameters<T>) => Promise<ReturnType<T>>;
function syncFunc(a: number, b: string): boolean { return true; }
type AsyncFunc = Asyncify<typeof syncFunc>; // (a: number, b: string) => Promise<boolean>
18.3 函数组合类型
为函数组合操作创建类型安全的类型:
typescript复制type Compose<A, B, C> = (f: (b: B) => C, g: (a: A) => B) => (a: A) => C;
const compose: Compose<string, string, string> = (f, g) => x => f(g(x));
19. 函数与可变参数
19.1 元组类型与剩余参数
结合元组类型和剩余参数创建类型安全的可变参数函数:
typescript复制function callWithArgs<T extends any[], R>(
fn: (...args: T) => R,
...args: T
): R {
return fn(...args);
}
callWithArgs((a: number, b: string) => `${a} ${b}`, 1, 'test'); // OK
callWithArgs((a: number, b: string) => `${a} ${b}`, 'test', 1); // Error
19.2 可变参数元组
TypeScript 4.0引入了可变参数元组类型:
typescript复制function concat<T extends unknown[], U extends unknown[]>(
arr1: [...T],
arr2: [...U]
): [...T, ...U] {
return [...arr1, ...arr2];
}
const result = concat([1, 2], ['a', 'b']); // [number, number, string, string]
19.3 带标签的元组参数
为元组参数的元素添加标签提高可读性:
typescript复制function createUser(...args: [name: string, age: number, isAdmin: boolean]) {
// ...
}
createUser('Alice', 30, false); // 参数有明确的标签提示
20. 函数与性能考量
20.1 内联函数与性能
理解何时让函数内联:
typescript复制// 小函数适合内联
function add(a: number, b: number) { return a + b; }
// 复杂函数应该单独定义
function processData(data: ComplexType) {
// 复杂逻辑
}
20.2 避免不必要的闭包
闭包会带来内存开销,避免在不必要的地方创建:
typescript复制// 不好
function createFunctions() {
const result = [];
for (var i = 0; i < 10; i++) {
result.push(function() { console.log(i); });
}
return result;
}
// 好
function createFunctions() {
const result = [];
for (let i = 0; i < 10; i++) {
result.push(function() { console.log(i); });
}
return result;
}
20.3 尾调用优化
虽然TypeScript/JavaScript引擎对尾调用优化的支持有限,但了解这一概念仍有价值:
typescript复制function factorial(n: number, acc = 1): number {
if (n <= 1) return acc;
return factorial(n - 1, n * acc); // 尾调用
}
21. 函数与设计模式
21.1 工厂函数
使用函数创建对象实例:
typescript复制interface User {
name: string;
role: 'admin' | 'user';
}
function createUser(name: string, isAdmin = false): User {
return {
name,
role: isAdmin ? 'admin' : 'user'
};
}
21.2 策略模式
使用函数作为策略实现:
typescript复制type Strategy = (a: number, b: number) => number;
const strategies: Record<string, Strategy> = {
add: (a, b) => a + b,
subtract: (a, b) => a - b,
multiply: (a, b) => a * b
};
function calculate(strategy: string, a: number, b: number) {
return strategies[strategy]?.(a, b) ?? NaN;
}
21.3 观察者模式
使用回调函数实现简单观察者:
typescript复制class Observable<T> {
private observers: ((value: T) => void)[] = [];
subscribe(fn: (value: T) => void) {
this.observers.push(fn);
}
notify(value: T) {
this.observers.forEach(fn => fn(value));
}
}
22. 函数与错误处理
22.1 异常处理策略
定义统一的错误处理方式:
typescript复制type Result<T, E = Error> = { success: true; value: T } | { success: false; error: E };
function safeParseJSON(json: string): Result<any, SyntaxError> {
try {
return { success: true, value: JSON.parse(json) };
} catch (e) {
return { success: false, error: e as SyntaxError };
}
}
22.2 错误转换
将低级错误转换为更有意义的领域错误:
typescript复制class DomainError extends Error {
constructor(message: string) {
super(message);
this.name = 'DomainError';
}
}
function fetchResource(url: string) {
try {
// 获取资源
} catch (e) {
throw new DomainError(`Failed to fetch resource from ${url}`);
}
}
22.3 错误恢复
提供错误恢复机制:
typescript复制function withFallback<T>(fn: () => T, fallback: T): T {
try {
return fn();
} catch {
return fallback;
}
}
23. 函数与代码组织
23.1 功能拆分
将大函数拆分为小函数:
typescript复制// 不好
function processOrder(order: Order) {
// 验证订单
// 计算价格
// 应用折扣
// 保存订单
// 发送通知
}
// 好
function processOrder(order: Order) {
validateOrder(order);
const total = calculateTotal(order);
const discounted = applyDiscounts(total);
saveOrder(order);
sendNotification(order);
}
23.2 纯函数与副作用
区分纯函数和有副作用的函数:
typescript复制// 纯函数
function calculateTax(amount: number, rate: number): number {
return amount * rate;
}
// 有副作用的函数
function saveInvoice(invoice: Invoice): void {
database.save(invoice);
logger.log(`Invoice ${invoice.id} saved`);
}
23.3 函数组合
将多个小函数组合成复杂操作:
typescript复制const processUser = pipe(
validateInput,
normalizeData,
createUserRecord,
sendWelcomeEmail
);
const result = processUser(rawInput);
24. 函数与测试
24.1 可测试函数设计
编写易于测试的函数:
typescript复制// 不好 - 难以测试
function processData() {
const data = readFileSync('data.json');
const parsed = JSON.parse(data);
// 复杂处理
writeFileSync('output.json', JSON.stringify(result));
}
// 好 - 依赖注入
function processData(
read: () => string,
parse: (data: string) => any,
write: (data: string) => void
) {
const data = read();
const parsed = parse(data);
// 处理
write(JSON.stringify(result));
}
24.2 模拟函数
在测试中模拟函数行为:
typescript复制// 使用jest.fn()创建模拟函数
const mockFetch = jest.fn(() => Promise.resolve({
json: () => Promise.resolve({ data: 'test' })
}));
test('fetchData works', async () => {
const data = await fetchData('url', mockFetch);
expect(data).toEqual({ data: 'test' });
expect(mockFetch).toHaveBeenCalledWith('url');
});
24.3 快照测试
对纯函数进行快照测试:
typescript复制function formatUser(user: User): string {
return `${user.lastName}, ${user.firstName}`;
}
test('formatUser snapshot', () => {
const user = { firstName: 'John', lastName: 'Doe' };
expect(formatUser(user)).toMatchSnapshot();
});
25. 函数与文档
25.1 JSDoc注释
为函数添加详细的文档注释:
typescript复制/**
* 计算两个数的和
* @param a 第一个加数
* @param b 第二个加数
* @returns 两个数的和
* @example
* const result = add(2, 3); // 5
*/
function add(a: number, b: number): number {
return a + b;
}
25.2 TypeScript类型文档
利用类型信息自动生成文档:
typescript复制interface User {
/** 用户名 */
name: string;
/** 用户年龄 */
age: number;
}
/** 创建用户 */
function createUser(name: string, age: number): User {
return { name, age };
}
25.3 示例代码
在文档中包含可运行的示例:
typescript复制/**
* 格式化日期
* @example
* ```typescript
* const date = new Date('2023-01-01');
* console.log(formatDate(date)); // "2023/01/01"
* ```
*/
function formatDate(date: Date): string {
return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
}
26. 函数与性能分析
26.1 性能测量
测量函数执行时间:
typescript复制function measure<T>(fn: () => T): { result: T; time: number } {
const start = performance.now();
const result = fn();
const end = performance.now();
return { result, time: end - start };
}
const { result, time } = measure(() => expensiveCalculation(1000));
console.log(`Calculation took ${time}ms`);
26.2 性能优化
识别并优化热点函数:
typescript复制// 优化前
function sumOfSquares(numbers: number[]): number {
return numbers.map(n => n * n).reduce((a, b) => a + b, 0);
}
// 优化后 - 减少中间数组
function sumOfSquares(numbers: number[]): number {
let sum = 0;
for (const n of numbers) {
sum += n * n;
}
return sum;
}
26.3 内存分析
关注函数内存使用:
typescript复制// 可能造成内存泄漏
function createClosures() {
const closures = [];
for (let i = 0; i < 1000; i++) {
closures.push(() => console.log(i));
}
return closures;
}
// 更好的方式
function createSafeClosures() {
const closures = [];
for (let i = 0; i < 1000; i++) {
const value = i;
closures.push(() => console.log(value));
}
return closures;
}
27. 函数与安全
27.1 输入验证
验证函数输入:
typescript复制function processInput(input: unknown) {
if (typeof input !== 'string') {
throw new Error('Invalid input type');
}
// 处理字符串
}
27.2 沙箱执行
安全执行不受信任的代码:
typescript复制function safeEval(code: string, context: object = {}) {
const proxy = new Proxy(context, {
has: () => true,
get: (target, prop) => {
if (prop === 'eval') throw new Error('eval is not allowed');
return target[prop];
}
});
return Function('"use strict";return (' + code + ')').bind(proxy)();
}
27.3 防注入
防止SQL/命令注入:
typescript复制function queryDatabase(sql: string, params: any[]) {
// 使用参数化查询而不是字符串拼接
return db.query(sql, params);
}
28. 函数与并发
28.1 避免竞态条件
处理异步操作的竞态条件:
typescript复制let lastRequestId = 0;
async function fetchData(url: string) {
const requestId = ++lastRequestId;
const response = await fetch(url);
if (requestId !== lastRequestId) return;
// 处理响应
}
28.2 限制并发
控制并发请求数量:
typescript复制async function withConcurrencyLimit<T>(
tasks: (() => Promise<T>)[],
limit: number
): Promise<T[]> {
const results: T[] = [];
const executing = new Set<Promise<T>>();
for (const task of tasks) {
const p = task().then(res => {
executing.delete(p);
return res;
});
executing.add(p);
results.push(await p);
if (executing.size >= limit) {
await Promise.race(executing);
}
}
return Promise.all(results);
}
28.3 共享状态管理
安全地管理共享状态:
typescript复制function createCounter() {
let count = 0;
const queue: (() => void)[] = [];
async function increment() {
return new Promise<void>(resolve => {
queue.push(() => {
count++;
resolve();
});
if (queue.length === 1) processQueue();
});
}
async function processQueue() {
while (queue.length) {
const task = queue[0];
await task();
queue.shift();
}
}
return { increment, getCount: () => count };
}
29. 函数与调试
29.1 调试工具
利用调试工具分析函数:
typescript复制// 使用debugger语句
function complexCalculation(input: number) {
debugger; // 执行会在此暂停
// 复杂计算
}
// 使用console.trace
function a() { b(); }
function b() { c(); }
function c() { console.trace(); }
a(); // 打印调用栈
29.2 日志调试
添加有意义的日志:
typescript复制function processOrder(order: Order) {
console.time('processOrder');
try {
console.log('Processing order', order.id);
// 处理订单
console.log('Order processed successfully');
} catch (error) {
console.error('Failed to process order', error);
throw error;
} finally {
console.timeEnd('processOrder');
}
}
29.3 性能剖析
使用性能剖析API:
typescript复制function profile(fn: Function, name: string) {
return function(...args: any[]) {
performance.mark(`${name}-start`);
const result = fn(...args);
performance.mark(`${name}-end`);
performance.measure(name, `${name}-start`, `${name}-end`);
return result;
};
}
const profiledFn = profile(expensiveCalculation, 'expensiveCalc');
profiledFn();
30. 函数与未来特性
30.1 管道操作符
了解即将到来的管道操作符:
typescript复制// 提案阶段
const result = value
|> double(%)
|> increment(%)
|> square(%);
30.2 模式匹配
函数式编程中的模式匹配:
typescript复制// 提案阶段
function handleResponse(response) {
return match(response) {
{ status: 200, data } => processData(data),
{ status: 404 } => logError('Not found'),
{ status } if (status >= 500) => logError('Server error')
};
}
30.3 装饰器元数据
装饰器元数据提案:
typescript复制// 提案阶段
@defineElement('my-component')
class MyComponent {
@reactive count = 0;
@on('click')
handleClick() {
this.count++;
}
}
31. 函数与跨平台开发
31.1 同构函数
编写可在客户端和服务器端运行的函数:
typescript复制function isBrowser(): boolean {
return typeof window !== 'undefined' && typeof document !== 'undefined';
}
function getEnvironment() {
return isBrowser() ? 'browser' : 'server';
}
31.2 平台特定实现
根据平台提供不同实现:
typescript复制interface Storage {
getItem(key: string): string | null;
setItem(key: string, value: string): void;
}
const storage: Storage = isBrowser()
? window.localStorage
: require('node-localstorage').LocalStorage('./scratch');
31.3 条件导出
使用package.json的条件导出:
typescript复制// package.json
{
"exports": {
"browser": "./browser.js",
"node": "./node.js"
}
}
// 使用
import { storage } from 'my-package'; // 自动选择正确实现
32. 函数与Web Workers
32.1 在Worker中运行函数
将计算密集型函数移到Worker:
typescript复制// main.ts
const worker = new Worker('worker.js');
worker.postMessage({ type: 'calculate', data: 1000 });
worker.onmessage =
