Appearance
可选参数
JavaScript中的函数经常需要一个可变数量的参数。例如, number 的 toFixed 方法需要一个可选的数字计数。
typescript
function f(n: number) {
console.log(n.toFixed()); // 0 个参数
console.log(n.toFixed(3)); // 1 个参数
}
我们可以在TypeScript中通过将参数用 ? 标记:
typescript
function f(x?: number) {
// ...
}
f(); // 正确
f(10); // 正确
虽然参数被指定为 number 类型,但 x 参数实际上将具有 number | undefined 类型,因为在 JavaScript 中未指定的参数会得到 undefined 的值。
你也可以提供一个参数默认值。
typescript
function f(x = 10) {
// ...
}
现在在 f 的主体中, x 将具有 number 类型,因为任何 undefined 的参数将被替换为 10 。请注意,当一个参数是可选的,调用者总是可以传递未定义的参数,因为这只是模拟一个 "丢失 "的参数:
typescript
declare function f(x?: number): void;
// 以下调用都是正确的
f();
f(10);
f(undefined);
回调中的可选参数
一旦你了解了可选参数和函数类型表达式,在编写调用回调的函数时就很容易犯以下错误:
typescript
function myForEach(arr: any[], callback: (arg: any, index?: number) => void) {
for (let i = 0; i < arr.length; i++) {
callback(arr[i], i);
}
}
我们在写 index? 作为一个可选参数时,通常是想让这些调用都是合法的:
typescript
myForEach([1, 2, 3], (a) => console.log(a));
myForEach([1, 2, 3], (a, i) => console.log(a, i));
这实际上意味着回调可能会被调用,只有一个参数。换句话说,该函数定义说,实现可能是这样的:
typescript
function myForEach(arr: any[], callback: (arg: any, index?: number) => void) {
for (let i = 0; i < arr.length; i++) {
// 我现在不想提供索引
callback(arr[i]);
}
}
反过来,TypeScript会强制执行这个意思,并发出实际上不可能的错误:
typescript
myForEach([1, 2, 3], (a, i) => {
console.log(i.toFixed())
})
在JavaScript中,如果你调用一个形参多于实参的函数,额外的参数会被简单地忽略。TypeScript的行为也是如此。参数较少的函数(相同的类型)总是可以取代参数较多的函数的位置。
当为回调写一个函数类型时,永远不要写一个可选参数,除非你打算在不传递该参数的情况下调用函数