TypeScript 中的函数类型和函数重载
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');
}
在这个例子中,我们定义了三个函数:
f
函数是一个普通的加法函数,我们还给它添加了一个version
属性。foo1
是一个返回void
类型的函数,但我们尝试在其中返回一个值,这是不允许的。foo2
是一个返回never
类型的函数,因为它总是抛出异常,永远不会正常执行完。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