讲解
函数是 JavaScript 的一等公民,TypeScript 为函数的每个环节都提供了类型工具。参数标注在函数章节已经见过,本章补齐全貌:可选参数(name?: string,等价于 name: string | undefined)、默认参数(count: number = 1,有默认值时类型可省略且参数自动变为可选)、剩余参数(...items: string[],类型必须是数组)。注意可选参数只能出现在必填参数之后。
函数本身的类型写法有两种:箭头形式 (a: number, b: number) => number 常用于 type 别名和接口成员;方法形式 add(a: number, b: number): number 只用于对象类型/接口内部。把函数赋值给变量或当参数传递时,TypeScript 会检查参数和返回值是否兼容——参数可以「少接」(传三个参数的回调赋给声明只要一个参数的类型是合法的,方便 forEach 这类 API),返回值则必须严格遵守。
还有一个常用点:回调参数的类型推断。把函数传给类型已知的 API(如数组的 map)时,回调参数不用标注,TypeScript 会从 map 的签名反推。这叫上下文类型(contextual typing),是「能推断就不标注」原则在函数上的体现。
示例
可选参数、默认参数、剩余参数:
function buildUrl(path: string, query?: string, secure: boolean = true): string {
const scheme = secure ? "https" : "http";
const suffix = query === undefined ? "" : `?${query}`;
return `${scheme}://example.com${path}${suffix}`;
}
function joinAll(sep: string, ...parts: string[]): string {
return parts.join(sep);
}
console.log(buildUrl("/docs", "page=2"));
console.log(buildUrl("/old", undefined, false));
console.log(joinAll("-", "a", "b", "c"));
函数类型别名与高阶函数:
type Formatter = (value: number) => string;
const asCurrency: Formatter = (v) => `¥${v.toFixed(2)}`;
const asPercent: Formatter = (v) => `${(v * 100).toFixed(0)}%`;
function showAll(values: number[], format: Formatter): void {
for (const v of values) {
console.log(format(v));
}
}
showAll([19.9, 0.85], asCurrency);
showAll([0.85], asPercent);
上下文类型:回调参数免标注,且「少接参数」合法:
const names: string[] = ["小林", "小陈", "小周"];
// index 参数自动推断为 number;只用第一个参数也合法
const labels: string[] = names.map((name, index) => `${index + 1}. ${name}`);
console.log(labels);
names.forEach((name) => console.log(`你好,${name}`));
常见坑
- 可选参数放错位置:function f(a?: number, b: number) 直接编译错误——可选参数之后不能有必填参数(除非用联合类型变通,不推荐)。
- 给有默认值的参数再标 undefined:默认参数已经是「可不传」,写成 count: number | undefined = 1 是自相矛盾的噪音。
- 以为参数个数必须严格一致:回调赋值时实参函数可以比声明少用几个参数(多出来的会被忽略),这是刻意设计,配合数组方法很舒服。
- void 返回类型的误解:声明返回 void 的函数类型可以接受返回任何值的函数(返回值被忽略),所以 forEach 里写 return 不报错。
小结
参数三板斧:可选 ?、默认 =、剩余 ...;函数类型用箭头形式表达,赋值时检查参数与返回值兼容性;上下文类型让回调参数免标注。下一章讲联合类型与字面量类型——精确表达「几个确定的值之一」。