Appearance
基础篇-函数
声明方式
- 通过 function
- 通过变量
- 通过接口
- 通过类型别名
ts
// 函数定义
function add1(x: number, y: number) {
return x + y;
}
// 通过变量
let add2: (x: number, y: number) => number;
// 通过类型别名
let add3 = (x: number, y: number) => number;
// 通过类型别名
interface add4 {
(x: number, y: number): number;
}
函数声明方式创建函数,括号中规定了函数参数的类型;最后一个冒号后面规定函数返回值类型
js
function sum(x: number, y: number): number {
return x + y;
}
表达式方式创建函数,参数类型和返回值类型的规定与上面是一样的
js
let mySum = function (x: number, y: number): number {
return x + y;
};
上面的代码只对等号右侧的匿名函数进行了类型定义,而等号左边的 mySum,是通过赋值操作进行类型推论而推断出来的。如果需要我们手动给 mySum 添加类型,则应该是这样:
js
let mySum: (x: number, y: number) => number = function (
x: number,
y: number,
): number {
return x + y;
};
输入多余的(或者少于要求的)参数,是不被允许的
js
function sum(x: number, y: number): number {
return x + y;
}
sum(1, 2, 3);
//报错
js
function sum(x: number, y: number): number {
return x + y;
}
sum(1);
//报错
可选参数
可选参数必须在必选参数之后
js
const addR = (x: number, y: number, z?: number): number => {
return x + y;
};
console.log(addR(1, 2));
经过修改,参数 z 变为可选参数,检查通过。
默认参数
与 JavaScript 相同,在 TypeScript 里函数参数同样可以设置默认值,用法一致。
js
function add(x: number, y = 2): number {
return x + y;
}
根据类型推断机制,参数 y 为推断为 number 类型
剩余参数
与 JavaScript 相同。TypeScript 可以把所有参数收集到一个变量里。
WARNING
剩余参数必须在必选参数之后,可选参数不允许和剩余参数共同出现在一个函数内。
js
function add(x: number, ...rest: number[]) {
return x + rest.reduce((prev, curr) => prev + curr);
}
add(1, 2, 3); // 6
函数重载
重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。
比如,我们需要实现一个函数 reverse,
- 输入数字 123 的时候,输出反转的数字 321,
- 输入字符串 'hello' 的时候,输出反转的字符串 'olleh'。
利用联合类型,我们可以这么实现:
js
function reverse(x: number | string): number | string | undefined {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
然而这样有一个缺点,就是不能够精确的表达,输入为数字的时候,输出也应该为数字,输入为字符串的时候,输出也应该为字符串。 这时,我们可以使用重载定义多个 reverse 的函数类型:
js
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string | undefined {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
上例中,我们重复定义了多次函数 reverse,前几次都是函数定义,最后一次是函数实现。在编辑器的代码提示中,可以正确的看到前两个提示。 注意,TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。
js
function getUserInfo(name: string): string;
function getUserInfo(name: string, age: number): string;
function getUserInfo(name: string, age?: number): string | number {
if (age) {
return `我叫${name},年龄${age}岁了`;
} else {
return `我叫${name}`;
}
}
console.log(getUserInfo('黎明')); //正确
console.log(getUserInfo(123)); //错误
console.log(getUserInfo('黎明', 123)); //正确