函数的类型
函数声明(定义)
一个函数有输入和输出,要在 TypeScript 中对其进行约束,需要把输入和输出都考虑到,其中函数声明的类型定义较简单:
function sum(x: number, y: number): number {
return x + y;
}
注意,输入多余的(或者少于要求的)参数,是不被允许的:
function sum(x: number, y: number): number {
return x + y;
}
sum(1, 2, 3);
// index.ts(4,1): error TS2346: Supplied parameters do not match any signature of call target.
函数表达式
let mySum = function (x: number, y: number): number {
return x + y;
};
// 实际
let mySum: (x: number, y: number) => number = function (
x: number,
y: number
): number {
return x + y;
};
在 TypeScript 的类型定义中,
=>用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。
箭头函数
let add = (a: number, b: number): number => a + b;
用接口定义函数的形状
我们也可以使用接口的方式来定义一个函数需要符合的形状:
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function (source: string, subString: string) {
return source.search(subString) !== -1;
};
采用函数表达式|接口定义函数的方式时,对等号左侧进行类型限制,可以保证以后对函数名赋值时保证参数个数、参数类型、返回值类型不变。
可选参数
与接口中的可选属性类似,我们用 ? 表示可选的参数:
function buildName(firstName: string, lastName?: string) {
if (lastName) {
return firstName + " " + lastName;
} else {
return firstName;
}
}
let tomcat = buildName("Tom", "Cat");
let tom = buildName("Tom");
注意:可选参数后面不允许再出现必须参数。
参数默认值
在 ES6 中,我们允许给函数的参数添加默认值,TypeScript 会将添加了默认值的参数识别为可选参数:
function buildName(firstName: string, lastName: string = "Cat") {
return firstName + " " + lastName;
}
let tomcat = buildName("Tom", "Cat");
let tom = buildName("Tom");
此时就不受「可选参数必须接在必需参数后面」的限制了:
function buildName(firstName: string = "Tom", lastName: string) {
return firstName + " " + lastName;
}
let tomcat = buildName("Tom", "Cat");
let cat = buildName(undefined, "Cat");
注意:可选参数和默认参数不能同时使用。
剩余参数(*)
ES6 中,可以使用 ...rest 的方式获取函数中的剩余参数(rest 参数):
function push(array, ...items) {
items.forEach(function (item) {
array.push(item);
});
}
let a: any[] = [];
push(a, 1, 2, 3);
事实上,items 是一个数组。所以我们可以用数组的类型来定义它:
function push(array: any[], ...items: any[]) {
items.forEach(function (item) {
array.push(item);
});
}
let a = [];
push(a, 1, 2, 3);
this
ts 允许定义 this 的类型(js 不能),函数的第一个参数可以定义 this 的类型。
interface Obj {
user: number[];
add: (this: Obj, num: number) => void; // 定义this的类型为Obj,传递的参数类型为number,函数没有返回值
}
let obj: Obj = {
user: [1, 2, 3],
add(this: Obj, num: number) {
this.user.push(num);
},
};
obj.add(4);
函数重载
允许一个函数接受不同数量或类型的参数时,作出不同的处理。
let users: number[] = [1, 23, 4];
function findNum(): number[]; // 如果什么都不传入则查询全部
function findNum(id: number): number[]; // 传入id则根据id查询
function findNum(add: number[]): number[]; // 传入number类型数组就将其添加到数组里
function findNum(id?: number | number[]): number[] {
if (typeof id == "number") {
return users.filter((uId) => uId == id);
} else if (Array.isArray(id)) {
user.push(...id);
} else {
return user;
}
}
console.log(findNum()); // [1,23,4]
console.log(findNum(4)); // [4]
console.log(findNum([6, 7, 9])); // [1,23,4,6,7,9]