我是TypeScript的新手,并尝试将其与AngularJS一起使用。这是一个困扰我的情况,因为我无法从编译器中得到错误。
在Angular(AFAIK)中,资源提供程序具有get()
方法,该方法返回T
的实例,T
是类型参数。此方法有许多其他重载,可以接受params
或data
参数,可能还有成功和带有这样签名的错误处理程序:
interface IResourceSuccessCallbackFunction<T> {
(value: T, responseHeaders: Array<string>): void;
}
interface IResourceErrorCallbackFunction {
(httpResponse: string): void;
}
我从 corresponding declaration file at DefinitelyTyped 中获取灵感,为get
函数提供了这些重载:
interface IResourceClass<T> {
get(): T;
get(dataOrParams: any): T;
get(dataOrParams: any, success: IResourceSuccessCallbackFunction<T>): T;
get(success: IResourceSuccessCallbackFunction<T>, error?: IResourceErrorCallbackFunction): T;
get(params: any, data: any, success?: IResourceSuccessCallbackFunction<T>, error?: IResourceErrorCallbackFunction): T;
}
我的问题是这些定义允许我写这样的东西:
var resourceService: IResourceClass<number> = null;
var res1 = resourceService.get({ id: 1000 }, function() {
console.log("fail");
});
var res2 = resourceService.get(function(p: Phone) {
console.log(p);
}, function() {
console.log("fail");
});
显然,对于res1
,程序员通过将错误处理程序作为第二个参数传递出错,忘记了成功处理程序;对于res2
,假定的成功处理程序接受错误的类型Phone
而不是number
。
现在,我知道为什么这两个调用编译并且有效:最后一个重载版本总是匹配,因为它允许两个any
参数和两个可选参数,这些都不存在。所以我正在寻找一种方法来定义可以捕获这些错误的重载变体。例如,将any
替换为会说“不是函数”的类型,或者通过其他一些技巧替换。
这可能吗?
答案 0 :(得分:1)
如果可能,请使用any
删除重载。我不确定这是否适用于这种情况;这取决于API的工作原理。
res1
将永远是正常的,因为你不是必需的来使用TypeScript中的参数(想象一下,如果必须对Array进行三参数回调,那会有多烦人#的forEach)。
对于res2
,您有时可以通过添加“陷阱”重载来改善这种情况:
interface IResourceClass<T> {
get(): T;
get(success: IResourceSuccessCallbackFunction<T>, error?: IResourceErrorCallbackFunction): T;
get(otherFunction1: (...a: any[]) => void, otherFunction2: (...a: any[]) => void): { YOU_HAVE_FAILED: {}; };
get(dataOrParams: any): T;
get(dataOrParams: any, success: IResourceSuccessCallbackFunction<T>): T;
get(params: any, data: any, success?: IResourceSuccessCallbackFunction<T>, error?: IResourceErrorCallbackFunction): T;
}
var resourceService: IResourceClass<number> = null;
var res1 = resourceService.get({ id: 1000 }, function() {
console.log("fail");
});
// res2: { YOU_HAVE_FAILED: {} }
var res2 = resourceService.get(function(p: Phone) {
console.log(p);
}, function() {
console.log("fail");
});
这不会立即出现编译错误,但res2
的任何实际用法都是错误的。