在TypeScript参数签名中处理潜在的空参数
在我的应用程序中,我有一个服务,它的方法被多次使用。一个方法接受一系列这样的参数(在我的示例中,参数的名称/指示是不相关的) 现在我需要扩展它,得到第四个可选参数,如下所示:在TypeScript参数签名中处理潜在的空参数,typescript,Typescript,在我的应用程序中,我有一个服务,它的方法被多次使用。一个方法接受一系列这样的参数(在我的示例中,参数的名称/指示是不相关的) 现在我需要扩展它,得到第四个可选参数,如下所示: doSomething(url: string, data: any, qParams?: QueryParams, headers?: HeadersType) {} 请注意,QueryParams和HeadersType是我编写的两种自定义类型。但是,在某些情况下,qParams将为空,并且标头将包含headersT
doSomething(url: string, data: any, qParams?: QueryParams, headers?: HeadersType) {}
请注意,QueryParams
和HeadersType
是我编写的两种自定义类型。但是,在某些情况下,qParams
将为空,并且标头将包含headersType
对象。因此,在某些情况下,我将调用方法,如sodoSomething(urlValue,dataVal)
或doSomething(urlVal,dataVal,qParamsVal)
或doSomething(urlVal,dataVal,qParamsVal,headersVal)
当我想要使用headersVal
而不是qParamsVal
时,防止必须在参数列表中输入空值的最佳方法是什么。我意识到我可以用键传递一个对象,但我可以使用扩展操作符或其他东西。我使用的是TypeScript,我的应用程序是用Angular2编写的
非常感谢
请注意,QueryParams和HeadersType是我编写的两种自定义类型。[…]当我想要headersVal而不是qParamsVal时,防止在参数列表中输入空值的最佳方法是什么
在这种情况下,为doSomething
创建附加值可能是可行的。这将使方法定义稍微复杂化,但会产生一个干净的调用签名:
// Callable signatures:
doSomething(url: string, data: any, qParams?: QueryParams);
doSomething(url: string, data: any, headers?: HeadersType);
doSomething(url: string, data: any, qParams?: QueryParams, headers?: HeadersType);
// Method implementation:
doSomething(url: string, data: any, qParamsOrHeaders?: QueryParams | HeadersType, headers?: HeadersType) {
// The function body should determine which overload signature was used:
if (qParamsOrHeaders instanceof QueryParams && headers instanceof HeadersType) {
// used signature: (string, any, QueryParams, HeadersType)
// ...
} else if (qParamsOrHeaders instanceof HeadersType) {
// used signature: (string, any, HeadersType)
// ...
} else if (qParamsOrHeaders instanceof QueryParams) {
// used signature: (string, any, QueryParams)
// ...
} else {
// used signature: (string, any)
// ...
}
}
显然,这要求
QueryParams
和HeadersType
是实际的类类型。当您有4个参数时,将它们作为具有4个属性的对象传递可能是有意义的,其中一些属性是可选的
您可以在调用时使用,也可以在定义方法时为参数使用,因此调用方法的各种方法如下所示
doSomething({url, data}) // when actual parameters names match args names exactly
doSomething({url: urlVal, data: dataVal}); // when they don't
doSomething({url: urlVal, data: dataVal, qParams: qParamsVal});
doSomething({url: urlVal, data: dataVal, headers: headersVal});
doSomething({url, data, qParams, headers: headersVal});
您必须为参数定义一个接口,因此在定义函数时会有一些名称重复:
interface DoSomething {
url: string;
data: any;
qParams?: QueryParams;
headers?: HeadersType;
}
doSomething({url, data, qParams, headers}: DoSomething): void {
....
if (qParams) {
....
}
}
优点是参数总是被命名的,并且在调用方法时,您不必记住可选参数的确切顺序和插入的空值数量
interface DoSomething {
url: string;
data: any;
qParams?: QueryParams;
headers?: HeadersType;
}
doSomething({url, data, qParams, headers}: DoSomething): void {
....
if (qParams) {
....
}
}