如何使某些功能参数为不带默认值的可选参数而另一些功能参数为默认值呢?

时间:2019-06-15 15:01:20

标签: javascript typescript

我写了一个函数

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不是可选的,我认为在上述两个可选参数之间不能存在强制性参数。

我发现的一种方法是通过将cancelToken的值设置为默认值并删除问号来使undefined为可选。

但是我想知道这是否是tsc中的错误,应该在编译的JS中将undefined作为cancelToken的默认值,还是我正在做某种事情错误在这里?

1 个答案:

答案 0 :(得分:3)

  

但是在JS中,cancelToken不是可选的,我认为在上述两个可选参数之间不能存在强制性参数。

在JavaScript中,所有参数是可选的。

  

但是我想知道这是否是tsc中的错误,应该在编译的JS中将undefined作为cancelToken的默认值,还是我正在做某种事情错误在这里?

以上都不是。 :-)默认情况下,JavaScript函数的所有参数均为可选,如果未提供默认值,则默认值为undefined。之间的唯一区别:

function foo(arg = undefined) { }

function foo(arg) { }

foo表示的foo.length arity (期望的参数数量)在第一种情况下为0,而{{ 1}}。从字面上看,这是唯一的区别。

区分JavaScript / TypeScript可选参数(和TypeScript的函数重载)与函数重载非常重要,因为它是用其他语言(如C#或Java)处理的。在JavaScript和TypeScript中,如果要允许人们离开不在参数列表末尾的参数,则必须处理将自己周围的参数改组。

考虑以下简单示例:

1

on the playground

请注意,您不能只忽略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

on the playground

如果您使用TypeScript的函数重载,它将允许您从类型角度忽略中间参数,但是您的实现必须处理将实际收到的参数值改写为:

foo("two", undefined, {});

on the playground

如果您有重载但没有在实现中进行改组,则最终会导致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拥有{{1 }}:

o

on the playground

所有这些都源于这样的事实,即静态类型信息在运行时不存在,并且实际上只有一个函数。

(当您在代码中写入undefined时,TypeScript可能输出// 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 ,它知道它仅与第二个重载签名匹配,但这是一个超越了TypeScript设计人员当前愿意做的事情。:-))