Typescript 中的 XHR 拦截器
XHR Interceptor in Typescript
为什么 Typescript 中不允许使用以下猴子补丁?
const oldXHROpen = window.XMLHttpRequest.prototype.open
window.XMLHttpRequest.prototype.open = function (
method: string,
url: string
): void {
return oldXHROpen.apply(this, [method, url])
}
它给出了以下错误:
Argument of type '[string, string]' is not assignable to parameter of type '[method: string, url: string | URL, async: boolean, username?: string | null | undefined, password?: string | null | undefined]'.
Source has 2 element(s) but target requires 3.
然而,在查看 open
的定义时,有一种方法只需要两个参数。
open(method: string, url: string | URL): void;
这是 TypeScript 的设计限制;有关详细信息,请参阅 microsoft/TypeScript#38353。
TypeScript standard library's typings for the XHMLHttpRequest.open()
method 看起来像这样:
interface XMLHttpRequest {
open(method: string, url: string | URL): void;
open(method: string, url: string | URL, async:
boolean, username?: string | null, password?: string | null): void;
}
有两个调用签名,这使得 open()
成为 TypeScript 中的 overloaded 方法。如果直接调用重载的方法或函数,编译器会select根据你传入的参数重载其中之一
但它不能纯粹在类型级别上做到这一点。如果您开始以编程方式操作重载函数类型的类型,编译器将立即选择一个调用签名,而不会尝试找出最适合这种情况的调用签名。通常这是最后一个调用签名。
在这种情况下,假设您 the --strictBindCallApply
compiler option enabled, the apply()
method for CallableFunction
只看到 XHMLHttpRequest.open()
的第二个调用签名。该调用签名至少需要三个参数,因此当您 apply()
其中两个参数时编译器会生气。哎呀
这种情况下的解决方法是手动将 oldXHROpen
的类型从一对调用签名扩展为您尝试支持的单个调用签名。由于扩大是一项安全操作,您可以使用 type annotation 来执行此操作并且不会放弃任何类型安全性:
const oldXHROpen: (method: string, url: string | URL) => void =
window.XMLHttpRequest.prototype.open // okay
一旦你这样做,apply()
方法只会看到你关心的 open()
调用签名,一切正常:
window.XMLHttpRequest.prototype.open = function (
method: string,
url: string
): void {
return oldXHROpen.apply(this, [method, url]) // okay
}
为什么 Typescript 中不允许使用以下猴子补丁?
const oldXHROpen = window.XMLHttpRequest.prototype.open
window.XMLHttpRequest.prototype.open = function (
method: string,
url: string
): void {
return oldXHROpen.apply(this, [method, url])
}
它给出了以下错误:
Argument of type '[string, string]' is not assignable to parameter of type '[method: string, url: string | URL, async: boolean, username?: string | null | undefined, password?: string | null | undefined]'.
Source has 2 element(s) but target requires 3.
然而,在查看 open
的定义时,有一种方法只需要两个参数。
open(method: string, url: string | URL): void;
这是 TypeScript 的设计限制;有关详细信息,请参阅 microsoft/TypeScript#38353。
TypeScript standard library's typings for the XHMLHttpRequest.open()
method 看起来像这样:
interface XMLHttpRequest {
open(method: string, url: string | URL): void;
open(method: string, url: string | URL, async:
boolean, username?: string | null, password?: string | null): void;
}
有两个调用签名,这使得 open()
成为 TypeScript 中的 overloaded 方法。如果直接调用重载的方法或函数,编译器会select根据你传入的参数重载其中之一
但它不能纯粹在类型级别上做到这一点。如果您开始以编程方式操作重载函数类型的类型,编译器将立即选择一个调用签名,而不会尝试找出最适合这种情况的调用签名。通常这是最后一个调用签名。
在这种情况下,假设您 the --strictBindCallApply
compiler option enabled, the apply()
method for CallableFunction
只看到 XHMLHttpRequest.open()
的第二个调用签名。该调用签名至少需要三个参数,因此当您 apply()
其中两个参数时编译器会生气。哎呀
这种情况下的解决方法是手动将 oldXHROpen
的类型从一对调用签名扩展为您尝试支持的单个调用签名。由于扩大是一项安全操作,您可以使用 type annotation 来执行此操作并且不会放弃任何类型安全性:
const oldXHROpen: (method: string, url: string | URL) => void =
window.XMLHttpRequest.prototype.open // okay
一旦你这样做,apply()
方法只会看到你关心的 open()
调用签名,一切正常:
window.XMLHttpRequest.prototype.open = function (
method: string,
url: string
): void {
return oldXHROpen.apply(this, [method, url]) // okay
}