阿里云主机折上折
  • 微信号
Current Site:Index > Function type definition

Function type definition

Author:Chuan Chen 阅读数:19223人阅读 分类: TypeScript

TypeScript's function type definitions provide powerful tools for describing the input and output behavior of functions. Through type annotations and interfaces, parameters and return values can be precisely constrained, while advanced features like overloading and generics are also supported.

Basic Syntax of Function Types

Function types consist of parameter types and a return type, expressed using arrow syntax:

type MathOperation = (a: number, b: number) => number;

This type defines a function that takes two numeric parameters and returns a number. In practice:

const add: MathOperation = (x, y) => x + y;
const multiply: MathOperation = (x, y) => x * y;

Optional and Default Parameters

TypeScript allows defining optional parameters and parameters with default values:

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!"

Typing Rest Parameters

For handling variable numbers of arguments, rest parameter syntax can be used:

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

Function Overloading

TypeScript supports function overloading, allowing multiple type definitions for the same function:

// Overload signatures
function reverse(str: string): string;
function reverse<T>(arr: T[]): T[];

// Implementation signature
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]

Generic Functions

Generics enable functions to handle multiple types without losing type information:

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"

Higher-Order Function Types

Handling functions as parameters or return values:

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"]

Constructor Types

Using the new keyword to define constructor types:

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 }

Async Function Types

Handling Promise return values:

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));

Combining Function Types with Interfaces

Interfaces can fully describe function types:

interface SearchFunc {
  (source: string, subString: string): boolean;
}

const mySearch: SearchFunc = (src, sub) => {
  return src.includes(sub);
};

console.log(mySearch('TypeScript', 'Script')); // true

Type Inference and Contextual Typing

TypeScript can infer function types based on context:

const names = ['Alice', 'Bob', 'Charlie'];

// Infers item type as string
names.map(item => item.toUpperCase());

// Explicit typing
names.map((item: string) => item.length);

Complex Function Type Examples

Combining multiple features into complex type definitions:

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 {
  // Actual implementation
}

addEventListener('click', (e) => {
  console.log(`Clicked at (${e.clientX}, ${e.clientY})`);
});

addEventListener('keydown', (e) => {
  console.log(`Key pressed: ${e.key}`);
});

Function Type Compatibility

TypeScript uses a structural type system with function type compatibility rules:

type Handler = (a: number, b: number) => void;

// Fewer parameters are compatible
const handler1: Handler = (a) => console.log(a);
// Parameter types are compatible
const handler2: Handler = (a: number, b: number, c?: string) => console.log(a + b);
// Return type compatibility
const handler3: Handler = () => {};

Advanced Patterns for Function Types

Using conditional and mapped types to create flexible function types:

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

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.