《TypeScript全面指南》第八章:TypeScript 的函数类型

173 阅读3分钟

简介

在 TypeScript 中,函数是执行某种操作或返回值的主要手段。TypeScript 允许为函数的输入和输出定义类型,以提供更强的类型安全。

Function 类型

在 TypeScript 中,可以为函数定义类型,这包括参数的类型返回值的类型

function greet(name: string): string {
    return "Hello, " + name;
}

在这里,greet 函数接受一个 string 类型的参数并返回一个 string 类型的值。

箭头函数

箭头函数提供了一个更简洁的方式来定义函数,并保留了 this 的值。它们的类型规则与普通函数相同。

const greet = (name: string): string => {
    return "Hello, " + name;
}

可选参数

TypeScript 允许函数参数是可选的。这是通过在参数名后加上 ? 符号来实现的。

function greet(name?: string): string {
    if (name) {
        return "Hello, " + name;
    } else {
        return "Hello";
    }
}

参数默认值

可以为函数的参数提供默认值。如果该参数没有被传入,就会使用默认值。

function greet(name = "World"): string {
    return "Hello, " + name;
}

参数解构

参数解构允许将对象或数组解构为单独的参数。

function greet({name, age}: {name: string, age: number}): string {
    return `Hello, ${name} who is ${age} years old.`;
}

rest 参数

使用 ... 操作符定义 rest 参数,允许你传递一个不确定数量的参数作为一个数组

function greet(name: string, ...titles: string[]): string {
    return "Hello, " + titles.join(" ") + " " + name;
}

readonly 只读参数

在函数参数中使用 readonly 修饰符确保函数不会修改其参数

function greet(readonly name: string): void {
    // name = "other"; // Error
}

void 类型

void 类型表示函数没有返回任何值

function logMessage(message: string): void {
    console.log(message);
}

never 类型

never 类型表示函数总是抛出错误或永远不会返回

function throwError(error: string): never {
    throw new Error(error);
}

局部类型

在函数体内部,你可以定义特定的类型,这些类型只在该函数内部有效。

function greet(name: string): string {
    type Greeting = { message: string };
    let greeting: Greeting = { message: "Hello, " + name };
    return greeting.message;
}

高阶函数

高阶函数是一个函数,它接受一个或多个函数作为参数或返回一个函数

function greeter(greeting: string): (name: string) => string {
    return (name) => {
        return greeting + ", " + name;
    };
}
function greeter(greeting: string): 
    (name: string) => 
    (age: string) => 
    (sex: string) => string {
    return name => age => sex => `${greeting}, ${name}. Age: ${age} ${sex}`;
}

函数重载

在 TypeScript 中,可以为同一个函数名称定义多个函数类型。

function greet(name: string): string;
function greet(age: number): number;
function greet(value: any): any {
    if (typeof value === "string") {
        return "Hello, " + value;
    } else {
        return value;
    }
}

构造函数

TypeScript 允许你为使用 new 关键字调用的函数定义类型。

type Constructor = new () => MyClass;

class MyClass {
    constructor() {
        console.log("Class instance created");
    }
}

function createInstance(ctor: Constructor): MyClass {
    return new ctor();
}

let instance = createInstance(MyClass);

这段 TypeScript 代码展示了如何使用类型别名定义构造函数的类型,并通过一个工厂函数动态地创建类的实例。

  1. 类型别名Constructor 是一个类型别名,代表一个没有参数并返回 MyClass 实例的构造函数。
  2. 类定义MyClass 是一个简单的类,其构造函数在每次创建类的实例时都会打印 "Class instance created"。
  3. 工厂函数createInstance 是一个函数,它接受一个类型为 Constructor 的参数(即一个构造函数),并使用这个构造函数创建并返回一个新的 MyClass 实例。
  4. 实例创建:最后,使用 createInstance 函数并传入 MyClass 作为参数来创建一个 MyClass 的实例,并将其赋值给 instance 变量。这会触发 MyClass 的构造函数,从而在控制台打印 "Class instance created"。

总之,这段代码演示了在 TypeScript 中如何使用类型别名和工厂函数模式来动态地创建类的实例。