Exists something like Overloads
for class
? I created previous issue associated with createRequest.ts and the function should be without error. I want to define same generics for class Data
like generics in createRequest
function.
Error
Error:(31, 52) TS2345: Argument of type 'RequestParameters' is not assignable to parameter of type 'RequestParameters & { as?: "json" | undefined; }'. Type 'RequestParameters' is not assignable to type '{ as?: "json" | undefined; }'. Types of property 'as' are incompatible. Type '"json" | "text" | undefined' is not assignable to type '"json" | undefined'. Type '"text"' is not assignable to type '"json" | undefined'.
Data.tsx
import * as React from 'react';
import createRequest, { RequestParameters, } from '../../createRequest';
interface P<R> {
children: (children: { createRequest: Data<R>['createRequest'] } & S<R>) => React.ReactNode;
parameters: RequestParameters;
url: Parameters<typeof createRequest>[0];
}
interface S<R> {
error: Error | null;
response: R | null;
}
class Data<R> extends React.Component<P<R>, S<R>> {
async componentDidMount () {
await this.createRequest();
}
state = { error: null, response: null, };
createRequest = async (): Promise<void> => {
this.setState(() => ({ error: null, response: null, }));
try {
const { parameters, url, } = this.props;
const response = await createRequest<R>(url, parameters); // <-- Error
this.onResponse(response);
} catch (error) {
this.onError(error);
}
};
onError (error: Error): void {
this.setState(() => ({ error, }));
throw error;
}
onResponse (response: R): void {
this.setState(() => ({ response, }));
}
render () {
const { children, } = this.props;
return children({ createRequest: this.createRequest, ...this.state, });
}
}
export default Data;
createRequest.ts
import { isString, } from '@redred/helpers';
export interface RequestParameters {
as?: 'json' | 'text';
body?: FormData | URLSearchParams | null | string;
headers?: Array<Array<string>> | Headers | { [name: string]: string };
method?: string;
queries?: { [name: string]: string };
}
async function createRequest (url: URL | string, parameters: RequestParameters & { as: 'text' }): Promise<string>;
async function createRequest<R> (url: URL | string, parameters: RequestParameters & { as?: 'json' }): Promise<R>;
async function createRequest<R> (url: URL | string, parameters: RequestParameters): Promise<R | string> {
if (isString(url)) {
url = new URL(url);
}
if (parameters.queries) {
for (const name in parameters.queries) {
url.searchParams.set(name, parameters.queries[name]);
}
}
const response = await fetch(url.toString(), parameters);
if (response.ok) {
switch (parameters.as) {
case 'json':
return response.json();
case 'text':
return response.text();
default:
return response.json();
}
}
throw new Error('!');
}
export default createRequest;