函数类型定义
TypeScript 的函数类型定义提供了强大的工具,用于描述函数的输入输出行为。通过类型注解和接口,可以精确约束参数和返回值,同时支持重载和泛型等高级特性。
函数类型的基本语法
函数类型包含参数类型和返回值类型两部分,用箭头语法表示:
type MathOperation = (a: number, b: number) => number;
这个类型定义了一个接收两个数字参数并返回数字的函数。实际使用时:
const add: MathOperation = (x, y) => x + y;
const multiply: MathOperation = (x, y) => x * y;
可选参数与默认参数
TypeScript 允许定义可选参数和带默认值的参数:
type GreetFunction = (name: string, prefix?: string) => string;
const greet: GreetFunction = (name, prefix = 'Hello') => {
return `${prefix}, ${name}!`;
};
console.log(greet('Alice')); // "Hello, Alice!"
console.log(greet('Bob', 'Hi')); // "Hi, Bob!"
剩余参数的类型定义
处理可变数量参数时,可以使用剩余参数语法:
type SumNumbers = (...numbers: number[]) => number;
const sum: SumNumbers = (...nums) => {
return nums.reduce((acc, curr) => acc + curr, 0);
};
console.log(sum(1, 2, 3)); // 6
console.log(sum(10, 20)); // 30
函数重载
TypeScript 支持函数重载,允许为同一个函数提供多个类型定义:
// 重载签名
function reverse(str: string): string;
function reverse<T>(arr: T[]): T[];
// 实现签名
function reverse(input: string | any[]): string | any[] {
if (typeof input === 'string') {
return input.split('').reverse().join('');
} else {
return input.slice().reverse();
}
}
console.log(reverse('TypeScript')); // "tpircSepyT"
console.log(reverse([1, 2, 3])); // [3, 2, 1]
泛型函数
泛型使函数能够处理多种类型而不丢失类型信息:
type IdentityFunc<T> = (arg: T) => T;
const identity: IdentityFunc<number> = (x) => x;
const stringIdentity: IdentityFunc<string> = (s) => s;
function firstElement<T>(arr: T[]): T | undefined {
return arr[0];
}
console.log(firstElement([1, 2, 3])); // 1
console.log(firstElement(['a', 'b', 'c'])); // "a"
高阶函数类型
处理函数作为参数或返回值的情况:
type MapperFunc<T, U> = (item: T) => U;
type ArrayMapper<T, U> = (arr: T[], mapper: MapperFunc<T, U>) => U[];
const numberToStringMapper: MapperFunc<number, string> = (n) => n.toString();
const mapArray: ArrayMapper<number, string> = (arr, mapper) => arr.map(mapper);
console.log(mapArray([1, 2, 3], numberToStringMapper)); // ["1", "2", "3"]
构造函数类型
使用 new
关键字定义构造函数类型:
interface Point {
x: number;
y: number;
}
type PointConstructor = new (x: number, y: number) => Point;
class Point2D implements Point {
constructor(public x: number, public y: number) {}
}
function createPoint(ctor: PointConstructor, x: number, y: number): Point {
return new ctor(x, y);
}
const point = createPoint(Point2D, 10, 20);
console.log(point); // Point2D { x: 10, y: 20 }
异步函数类型
处理 Promise 返回值的情况:
type FetchData = (url: string) => Promise<any>;
const fetchUser: FetchData = async (url) => {
const response = await fetch(url);
return response.json();
};
fetchUser('https://api.example.com/users/1')
.then(data => console.log(data));
函数类型与接口结合
接口可以完整描述函数类型:
interface SearchFunc {
(source: string, subString: string): boolean;
}
const mySearch: SearchFunc = (src, sub) => {
return src.includes(sub);
};
console.log(mySearch('TypeScript', 'Script')); // true
类型推断与上下文类型
TypeScript 能根据上下文推断函数类型:
const names = ['Alice', 'Bob', 'Charlie'];
// 推断出 item 类型为 string
names.map(item => item.toUpperCase());
// 显式类型
names.map((item: string) => item.length);
复杂函数类型示例
组合多种特性的复杂类型定义:
type EventHandler<E extends Event> = (event: E) => void;
type EventMap = {
click: MouseEvent;
keydown: KeyboardEvent;
};
function addEventListener<K extends keyof EventMap>(
type: K,
handler: EventHandler<EventMap[K]>,
options?: boolean | AddEventListenerOptions
): void {
// 实际实现
}
addEventListener('click', (e) => {
console.log(`Clicked at (${e.clientX}, ${e.clientY})`);
});
addEventListener('keydown', (e) => {
console.log(`Key pressed: ${e.key}`);
});
函数类型的兼容性
TypeScript 采用结构化类型系统,函数类型兼容规则:
type Handler = (a: number, b: number) => void;
// 参数少的情况兼容
const handler1: Handler = (a) => console.log(a);
// 参数类型兼容
const handler2: Handler = (a: number, b: number, c?: string) => console.log(a + b);
// 返回值类型兼容
const handler3: Handler = () => {};
函数类型的高级模式
使用条件类型和映射类型创建灵活的函数类型:
type Promisify<T> = T extends (...args: infer A) => infer R
? (...args: A) => Promise<R>
: T;
function promisify<F extends (...args: any[]) => any>(fn: F): Promisify<F> {
return ((...args: Parameters<F>) => {
return new Promise((resolve) => {
resolve(fn(...args));
});
}) as Promisify<F>;
}
const syncAdd = (a: number, b: number): number => a + b;
const asyncAdd = promisify(syncAdd);
asyncAdd(1, 2).then(result => console.log(result)); // 3
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn