I have a method defined that wraps fetch in order to automatically handle certain edge cases and provide a unified response class alerting system. I don't want to automatically parse responses as json (the platform will not only be requesting JSON) and came up with the idea to add to the fetch method's prototype a .json call to auto-parse and coerce the promise but found that I couldn't use the prototype when calling integratedFetch.json(//etc). Is is possible to add such a static method?
Example code:
const integratedFetch: (
input: RequestInfo,
init?: RequestInit | undefined,
options?: Partial<IntegratedFetchOptions>
) => Promise<Response> = (input, init, options) => {
return fetch(input, init).then(async (response) => {
const { status } = response;
const responseClass = getResponseClass(response);
if (responseClass) {
switch (Number(responseClass) as ResponseClass) {
case ResponseClass.Informational:
//etc
case ResponseClass.Successful:
//etc
default:
throw Error(`Response class ${responseClass} unrecognized`);
}
}
return Promise.resolve(response);
});
};
integratedFetch.prototype.json = <T>(input: RequestInfo, init?: RequestInit | undefined, options?: Partial<IntegratedFetchOptions>) =>
integratedFetch(input, init, options).then((response) => response.json() as Promise<T>);
With expected usage to be:
integratedFetch.json<MyType>(//request)
-vs-
integratedFetch(//request).then(r => r.json() as Promise<T>)
The current problem being that using integratedFetch.json()
gives the error "Property 'json' does not exist on type '(input: RequestInfo, init?: RequestInit | undefined, options?: Partial | undefined) => Promise<...>'.ts(2339)"
CodePudding user response:
Just assign the second function to a new property of the first function. Typescript keeps track of that. No adjust of the prototype
is necessary.
const foo = () => 123
foo.bar = () => 'hello'
foo() // 123
foo.bar() // "hello"
CodePudding user response:
Turns out I had to be a little more inventive with typedefs here...
type FetchParams = (input: RequestInfo, init?: RequestInit | undefined, options?: Partial<IntegratedFetchOptions>) => Promise<Response>;
type StaticParams = <T>(input: RequestInfo, init?: RequestInit | undefined, options?: Partial<IntegratedFetchOptions>) => Promise<T>;
const integratedFetch: IntegratedFetch = (input, init, options) => { //the previous implementation
integratedFetch.json = <T>(input: RequestInfo, init?: RequestInit | undefined, options?: Partial<IntegratedFetchOptions>) =>
integratedFetch(input, init, options).then((response) => response.json() as Promise<T>);
This avoids the TS2339 error and allows me to use the static method assigned to the function definition!