我写了一个函数
function patchItem = (id: string | number, data: object, params: object = {}, cancelToken?: CancelToken, additionalDispatchData: object = {})
{
}
在这里,我想使params
、cancelToken
和additionalDispatchData
参数可选,但不想给cancelToken
一个初始值。
上面的定义在打字稿中没有显示任何错误,并且编译完美。
上面的代码是用下面的js代码编译的
function patchItem = (id, data, params = {}, cancelToken, additionalDispatchData = {})
{
}
但是在 JS 中,cancelToken
不是可选的,我认为上述两个可选参数之间不能存在强制参数。
我发现的一种方法是通过将undefined
值作为默认值并删除问号来使cancelToken
可选。
但是我想知道这是否是tsc
中的错误,它应该给出undefined
作为默认值以在编译的JS中cancelToken
,或者我在这里犯了某种错误?
在JS中,
cancelToken
不是可选的,我认为上述两个可选参数之间不能存在强制性参数。
在 JavaScript 中,所有参数都是可选的。
但是我想知道这是否是
tsc
中的错误,它应该将undefined
作为默认值以在编译的JS中cancelToken
,或者我在这里犯了某种错误?
以上都不是。默认情况下,JavaScript 函数的所有参数都是可选的,如果未提供默认值,则默认值为undefined
。两者之间的唯一区别:
function foo(arg = undefined) { }
和
function foo(arg) { }
是foo
的arity(它期望的参数数量)由foo.length
表示,在第一种情况下将0
,在第二种情况下1
。这实际上是唯一的区别。
区分JavaScript/TypeScript可选参数(以及TypeScript的函数重载)与函数重载非常重要,因为它在其他语言(如C#或Java)中处理。在 JavaScript 和 TypeScript 中,如果你想让人们省略不在参数列表末尾的参数,你必须处理围绕自己的参数的洗牌。
考虑这个更简单的例子:
function foo(a: string, n?: number, o?: object): void
{
console.log(a, n, o);
}
foo("one", 1, {});
foo("two", {}); // Error: Argument of type '{}' is not assignable to parameter of type 'number'.
(在操场上)
请注意,不能只省略n
参数。你必须这样做:
foo("two", undefined, {});
(在操场上)
如果你使用 TypeScript 的函数重载,它将允许你从类型的角度省略中间的参数,但你的实现必须处理随机排列实际接收的参数值:
function foo(a: string, n: number, o: object): void;
function foo(a: string, o: object): void;
function foo(a: string, n?: any, o?: object): void
{
if (typeof n === "object") {
o = n;
n = undefined;
}
console.log(a, n, o);
}
foo("one", 1, {}); // "one", 1, {}
foo("two", {}); // "two", undefined, {}
(在操场上)
如果你有重载但没有在实现中进行洗牌,你最终会得到n
引用一个对象,o
undefined
:
// Incorrect
function foo(a: string, n: number, o: object): void;
function foo(a: string, o: object): void;
function foo(a: string, n?: any, o?: object): void
{
console.log(a, n, o);
}
foo("one", 1, {}); // "one", 1, {}
foo("two", {}); // "two", {}, undefined
(在操场上)
这一切都源于这样一个事实,即静态类型信息在运行时不存在,实际上只有一个函数。
(当你在代码中编写foo("two", {})
时,TypeScript 可能会输出foo("two", undefined, {})
,并且它知道它只匹配第二个重载签名,但这超出了 TypeScript 设计人员目前愿意让它做的事情。