likes
comments
collection
share

TypeScript 中的函数类型和函数重载

作者站长头像
站长
· 阅读数 72

TypeScript 中的函数类型和函数重载

在 TypeScript 中,函数类型和函数重载是非常重要的概念。本文将详细介绍这两个概念以及它们的使用场景。

函数类型

在 TypeScript 中,我们可以将一个函数赋值给一个变量,并为该变量定义函数类型。例如:

typescript

复制

let a: {
    (x: number, y: number): number
};

a = (x: number, y: number) => x + y;

在这个例子中,我们定义了一个变量 a,它的类型是一个函数类型,该函数接受两个 number 类型的参数,并返回一个 number 类型的值。然后我们将一个箭头函数赋值给 a

函数重载

TypeScript 还支持函数重载,这意味着我们可以为同一个函数定义多个签名。当调用该函数时,TypeScript 会根据传入的参数类型选择合适的签名进行类型检查。例如:

typescript

复制

function f(x: number, y: number) {  return x + y; }
f.version = 1;

type voidFunc = () => void;
const foo1: voidFunc = () => 1; // 错误,因为 void 函数不能返回值

function foo2(): never {
    throw new Error('11');
}

function foo3(): number {
    if(Math.random() > 0.5) {
        return 100;
    }
    throw Error('something went wrong');
}

在这个例子中,我们定义了三个函数:

  1. f 函数是一个普通的加法函数,我们还给它添加了一个 version 属性。
  2. foo1 是一个返回 void 类型的函数,但我们尝试在其中返回一个值,这是不允许的。
  3. foo2 是一个返回 never 类型的函数,因为它总是抛出异常,永远不会正常执行完。
  4. foo3 是一个既可能返回 number 类型,也可能抛出异常的函数。

接下来我们看一个更复杂的函数重载示例:

typescript

复制

function reverse(str: string): string;
function reverse(arr: any[]): any[];
function reverse(stringOrArr: string | any []):string | any [] {
    if(typeof stringOrArr === 'string') {
        return stringOrArr.split(' ').reverse().join(' ');
    } else return stringOrArr.slice().reverse();
}

function add(x: number, y: number):number;
function add(arr1: any [], arr2: any[]): any[];
function add(x:number | any[], y: number | any[]): number | any[] {
    if(Array.isArray(x) && Array.isArray(y)) return [...x, ...y];
    if(typeof x === 'number' && typeof y === 'number') return x + y;  
    throw Error('something went wrong');
}

在这个例子中,我们定义了两个函数 reverse 和 add,它们都有多个重载签名。reverse 函数可以接受字符串或数组,并返回相应的反转结果。add 函数可以接受两个数字或两个数组,并返回相应的结果。

需要注意的是,函数重载声明的顺序很重要。TypeScript 会按照声明的顺序进行类型检查,一旦找到匹配的签名,就不会再往下检查了。所以最宽泛的签名应该放在最后,以防止覆盖其他更具体的签名。

构造函数类型

最后,我们还可以定义构造函数类型。构造函数类型描述了一个可以使用 new 关键字创建对象的函数。

typescript

复制

// 构造函数
class Animal{
    numLegs: number = 4;
}

type AnimalConstructor = new () => Animal;
// F 既可以当作普通函数执行,也可以当作构造函数使用。
type F = {
    new (s:string): object,
    (s: number): number,
}
function create(c: AnimalConstructor):Animal {
    return new c();
}
const animals = create(Animal);

在这个例子中,我们定义了一个 AnimalConstructor 类型,它描述了一个无参数的构造函数,返回一个 Animal 实例。我们还定义了一个 F 类型,它既可以当作普通函数使用,也可以当作构造函数使用。

总之,TypeScript 中的函数类型和函数重载是非常强大的特性,可以帮助我们更好地描述和约束函数的行为。合理使用这些特性可以提高代码的可读性和可维护性。

转载自:https://juejin.cn/post/7352817681895702540
评论
请登录