如何解决使用 Typescript 的 SWR Vercel 全局配置 为您的问题编写了一些自定义 TypeDef
我想用 SWR 配置创建一个对象来将它们设置为全局。我正在使用来自 swr 的 ConfigInterface 类型。
import { ConfigInterface } from 'swr';
import fetcher from 'api/axiosFetcher';
const swrConfig: ConfigInterface = {
fetcher,};
export default swrConfig;
问题是当我尝试在 SWRConfig 中使用这个对象时
<SWRConfig value={swrConfig}>
Type 'ConfigInterface<any,any,fetcherFn<any>>' is not assignable to type 'ConfigInterface<any,(...args: any) => any>'.
Types of property 'fetcher' are incompatible.
Type '((...args: any) => any) | null | undefined' is not assignable to type '((...args: any) => any) | undefined'.
Type 'null' is not assignable to type '((...args: any) => any) | undefined'.ts(2322)
我的抓取功能
const fetcher = <T>(url: string): Promise<T> =>
axiosInstance
.get(url)
.then((response) => {
if (response.statusText === 'OK') {
return response.data;
}
throw new Error(response.statusText);
})
.catch(({ response }) => {
throw new Error(response.statusText);
});
解决方法
为您的问题编写了一些自定义 TypeDef。
- 首先,将您的函数编写为一个 TypeScript Class,它接受一个泛型参数 (T)。通过这种方式,您可以对应用了 Mixin 的类应用约束 (T)
type FetcherConstructor<T = {}> = new (...args: any[]) => T;
- 我们的类只有在 url 参数传递一个字符串值时才有效——所需的 url 参数是一个实现应用约束的例子(上面提到过)
type FetcherAbstracted = FetcherConstructor<{
fetcher: (url: string,init?: RequestInit) => Promise<Response>;
}>;
如您所见,条件RequestInit接口相当广泛
interface RequestInit {
/**
* A BodyInit object or null to set request's body.
*/
body?: BodyInit | null;
/**
* A string indicating how the request will interact with the browser's cache to set request's cache.
*/
cache?: RequestCache;
/**
* A string indicating whether credentials will be sent with the request always,never,or only when sent to a same-origin URL. Sets request's credentials.
*/
credentials?: RequestCredentials;
/**
* A Headers object,an object literal,or an array of two-item arrays to set request's headers.
*/
headers?: HeadersInit;
/**
* A cryptographic hash of the resource to be fetched by request. Sets request's integrity.
*/
integrity?: string;
/**
* A boolean to set request's keepalive.
*/
keepalive?: boolean;
/**
* A string to set request's method.
*/
method?: string;
/**
* A string to indicate whether the request will use CORS,or will be restricted to same-origin URLs. Sets request's mode.
*/
mode?: RequestMode;
/**
* A string indicating whether request follows redirects,results in an error upon encountering a redirect,or returns the redirect (in an opaque fashion). Sets request's redirect.
*/
redirect?: RequestRedirect;
/**
* A string whose value is a same-origin URL,"about:client",or the empty string,to set request's referrer.
*/
referrer?: string;
/**
* A referrer policy to set request's referrerPolicy.
*/
referrerPolicy?: ReferrerPolicy;
/**
* An AbortSignal to set request's signal.
*/
signal?: AbortSignal | null;
/**
* Can only be null. Used to disassociate request from any Window.
*/
window?: any;
}
- 其中bodyInit类型定义如下
type BodyInit = Blob | BufferSource | FormData | URLSearchParams | ReadableStream<Uint8Array> | string;
- 而
Response
接口(在本例中为typeof fetcher
)具有以下响应接口作为其返回的负载
/** This Fetch API interface represents the response to a request. */
interface Response extends Body {
readonly headers: Headers;
readonly ok: boolean;
readonly redirected: boolean;
readonly status: number;
readonly statusText: string;
readonly trailer: Promise<Headers>;
readonly type: ResponseType;
readonly url: string;
clone(): Response;
}
在此处查看 mixins 以获得更多说明。
- 简单实用的实现
export default async function FetcherExample(
fetch: FetcherAbstracted
) {
const exactPath = 'docs/handbook/mixins.html';
const data: Response = await new fetch().fetcher(
`https://typescriptlang.org${exactPath}`,{
body: exactPath,method: 'GET',headers: {
'Content-Type': 'application/json'
// ...
},credentials: "include"
}
);
return await data.json();
}
为了清晰起见,现在将它们全部放在一个代码片段中
export type FetcherConstructor<T = {}> = new (...args: any[]) => T;
export type FetcherAbstracted = FetcherConstructor<{
fetcher: (url: string,init?: RequestInit) => Promise<Response>;
}>;
export default async function FetcherExample(
fetch: FetcherAbstracted
) {
const exactPath = 'docs/handbook/mixins.html';
const data: Response = await new fetch().fetcher(
`https://typescriptlang.org${exactPath}`,credentials: "include"
}
);
return await data.json();
}
更新
为了简洁地回答你的问题,这个钩子应该与 axios+SWR 一起使用,这类似于我上面写的参数约束泛型
type FetcherAbstracted = FetcherConstructor<{
fetcher: (url: string,init?: RequestInit) => Promise<Response>;
}>;
这么多,你可以将它用于你的 Axios fetcher 实现。
const fetcher: FetcherAbstracted = async (url: string) => {
try {
const res = await Axios.get(url);
return res.data;
} catch (error) {
throw error.response.data;
}
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。