如何使某些函数参数在没有默认值的情况下可选,而其他具有默认值的函数参数?



我写了一个函数

function patchItem = (id: string | number, data: object, params: object = {}, cancelToken?: CancelToken, additionalDispatchData: object = {})
{
}

在这里,我想使paramscancelTokenadditionalDispatchData参数可选,但不想给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) { }

fooarity(它期望的参数数量)由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引用一个对象,oundefined

// 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 设计人员目前愿意让它做的事情。

最新更新