阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 函数类型定义

函数类型定义

作者:陈川 阅读数:19224人阅读 分类: TypeScript

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

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌