Skip to content

Commit

Permalink
feat: turn most types into interfaces (arthurfiorette#615)
Browse files Browse the repository at this point in the history
* Turn most types into interfaces

* Turn 'CacheAxiosResponse' into a interface

* Update docs

* Change docs to be more didactic
  • Loading branch information
denis-rossati authored Jul 30, 2023
1 parent dbb0a3f commit 0199ad6
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 36 deletions.
24 changes: 24 additions & 0 deletions docs/src/guide/interceptors.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,27 @@ axios.interceptors.request.use((req) => req);
// This will be ran BEFORE the cache interceptor
axios.interceptors.response.use((res) => res);
```

---

## Extending types

When using axios-cache-interceptor, you'll note that it have a different type
than the defaults `AxiosInstance`, `AxiosRequestConfig` and `AxiosResponse`.
That's because was chosen to override axios's interfaces instead of extending,
to avoid breaking changes with other libraries.

However, this also means that when integrating with other packages or creating
your own custom interceptor, you need to override/extend our own types,
`CacheInstance`, `CacheRequestConfig` and `CacheAxiosResponse` to match your needs.

This can be done as shown below:

```ts
declare module 'axios-cache-interceptor' {
interface CacheRequestConfig<R = unknown, D = unknown> {
customProperty: string;
}
}
```

15 changes: 8 additions & 7 deletions src/cache/axios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import type { CacheInstance, CacheProperties } from './cache';
* @template D The type that the request body was
* @see https://axios-cache-interceptor.js.org/config/response-object
*/
export type CacheAxiosResponse<R = any, D = any> = AxiosResponse<R, D> & {
config: CacheRequestConfig<R, D>;
export interface CacheAxiosResponse<R = any, D = any> extends AxiosResponse<R, D> {
config: InternalCacheRequestConfig<R, D>;

/**
* The [Request ID](https://axios-cache-interceptor.js.org/guide/request-id) used in
Expand All @@ -46,15 +46,15 @@ export type CacheAxiosResponse<R = any, D = any> = AxiosResponse<R, D> & {
* @see https://axios-cache-interceptor.js.org/config/response-object#cached
*/
cached: boolean;
};
}

/**
* Options that can be overridden per request
*
* @template R The type returned by this response
* @template D The type for the request body
*/
export type CacheRequestConfig<R = any, D = any> = AxiosRequestConfig<D> & {
export interface CacheRequestConfig<R = any, D = any> extends AxiosRequestConfig<D> {
/**
* The [Request ID](https://axios-cache-interceptor.js.org/guide/request-id) used in
* this request.
Expand All @@ -81,12 +81,13 @@ export type CacheRequestConfig<R = any, D = any> = AxiosRequestConfig<D> & {
* @see https://axios-cache-interceptor.js.org/config/response-object#cache
*/
cache?: false | Partial<CacheProperties<R, D>>;
};
}

/** Cached version of type {@link InternalAxiosRequestConfig} */
export type InternalCacheRequestConfig<R = any, D = any> = CacheRequestConfig<R, D> & {
export interface InternalCacheRequestConfig<R = any, D = any>
extends CacheRequestConfig<R, D> {
headers: AxiosResponseHeaders;
};
}

/**
* Same as the AxiosInstance but with CacheRequestConfig as a config type and
Expand Down
10 changes: 7 additions & 3 deletions src/cache/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import type { CacheAxiosResponse, CacheRequestConfig } from './axios';
* @template R The type returned by this response
* @template D The type for the request body
*/
export type CacheProperties<R = unknown, D = unknown> = {
export interface CacheProperties<R = unknown, D = unknown> {
/**
* The time until the cached value is expired in milliseconds.
*
Expand Down Expand Up @@ -211,7 +211,7 @@ export type CacheProperties<R = unknown, D = unknown> = {
| CachedStorageValue
| StaleStorageValue
) => void | Promise<void>);
};
}

/**
* These are properties that are used and shared by the entire application.
Expand Down Expand Up @@ -342,4 +342,8 @@ export interface CacheInstance {
*
* @see https://axios-cache-interceptor.js.org/#/pages/development-mode
*/
export type DebugObject = { id?: string; msg?: string; data?: unknown };
export interface DebugObject {
id?: string;
msg?: string;
data?: unknown;
}
2 changes: 1 addition & 1 deletion src/cache/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { defaultKeyGenerator } from '../util/key-generator';
import type { AxiosCacheInstance } from './axios';
import type { CacheInstance, CacheProperties } from './cache';

export type CacheOptions = Partial<CacheInstance> & Partial<CacheProperties>;
export interface CacheOptions extends Partial<CacheInstance>, Partial<CacheProperties> {}

/**
* Apply the caching interceptors for a already created axios instance.
Expand Down
6 changes: 3 additions & 3 deletions src/interceptors/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ export function isMethodIn(
return methodList.some((method) => method === requestMethod);
}

export type ConfigWithCache<D> = CacheRequestConfig<unknown, D> & {
cache: Partial<CacheProperties>;
};
export interface ConfigWithCache<D> extends CacheRequestConfig<unknown, D> {
cache: Partial<CacheProperties<unknown, D>>;
}

/**
* This function updates the cache when the request is stale. So, the next request to the
Expand Down
4 changes: 2 additions & 2 deletions src/storage/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function isExpired(value: CachedStorageValue | StaleStorageValue): boolea
return value.ttl !== undefined && value.createdAt + value.ttl <= Date.now();
}

export type BuildStorage = Omit<AxiosStorage, 'get'> & {
export interface BuildStorage extends Omit<AxiosStorage, 'get'> {
/**
* Returns the value for the given key. This method does not have to make checks for
* cache invalidation or anything. It just returns what was previous saved, if present.
Expand All @@ -74,7 +74,7 @@ export type BuildStorage = Omit<AxiosStorage, 'get'> & {
key: string,
currentRequest?: CacheRequestConfig
) => MaybePromise<StorageValue | undefined>;
};
}

/**
* All integrated storages are wrappers around the `buildStorage` function. External
Expand Down
4 changes: 2 additions & 2 deletions src/storage/memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,10 @@ export function buildMemoryStorage(
return storage;
}

export type MemoryStorage = AxiosStorage & {
export interface MemoryStorage extends AxiosStorage {
data: Record<string, StorageValue>;
/** The job responsible to cleaning old entries */
cleaner: ReturnType<typeof setInterval>;
/** Tries to remove any invalid entry from the memory */
cleanup: () => void;
};
}
28 changes: 14 additions & 14 deletions src/storage/types.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { CacheAxiosResponse, CacheRequestConfig } from '../cache/axios';
import type { MaybePromise } from '../util/types';

export type CachedResponse = {
export interface CachedResponse {
data?: unknown;
headers: CacheAxiosResponse['headers'];
status: number;
statusText: string;
};
}

/** The value returned for a given key. */
export type StorageValue =
Expand All @@ -17,15 +17,15 @@ export type StorageValue =

export type NotEmptyStorageValue = Exclude<StorageValue, EmptyStorageValue>;

export type StaleStorageValue = {
export interface StaleStorageValue {
data: CachedResponse;
ttl?: number;
staleTtl?: undefined;
createdAt: number;
state: 'stale';
};
}

export type CachedStorageValue = {
export interface CachedStorageValue {
data: CachedResponse;
/**
* The number in milliseconds to wait after createdAt before the value is considered
Expand All @@ -35,37 +35,37 @@ export type CachedStorageValue = {
staleTtl?: number;
createdAt: number;
state: 'cached';
};
}

export type LoadingStorageValue = LoadingEmptiedStorageValue | LoadingStaledStorageValue;

export type LoadingEmptiedStorageValue = {
export interface LoadingEmptiedStorageValue {
data?: undefined;
ttl?: undefined;
staleTtl?: undefined;
createdAt?: undefined;
state: 'loading';
previous: 'empty';
};
}

export type LoadingStaledStorageValue = {
export interface LoadingStaledStorageValue {
state: 'loading';
data: CachedResponse;
ttl?: undefined;
staleTtl?: undefined;
createdAt: number;
previous: 'stale';
};
}

export type EmptyStorageValue = {
export interface EmptyStorageValue {
data?: undefined;
ttl?: undefined;
staleTtl?: undefined;

/** Defined when the state is cached */
createdAt?: undefined;
state: 'empty';
};
}

/**
* A storage interface is the entity responsible for saving, retrieving and serializing
Expand All @@ -74,7 +74,7 @@ export type EmptyStorageValue = {
* @default buildMemoryStorage
* @see https://axios-cache-interceptor.js.org/guide/storages
*/
export type AxiosStorage = {
export interface AxiosStorage {
/**
* Sets a new value for the given key
*
Expand Down Expand Up @@ -113,4 +113,4 @@ export type AxiosStorage = {
* @see https://axios-cache-interceptor.js.org/guide/storages#buildstorage
*/
get: (key: string, currentRequest?: CacheRequestConfig) => MaybePromise<StorageValue>;
};
}
8 changes: 4 additions & 4 deletions src/util/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export type CachePredicate<R = unknown, D = unknown> = Exclude<
undefined
>;

export type CachePredicateObject<R = unknown, D = unknown> = {
export interface CachePredicateObject<R = unknown, D = unknown> {
/** Matches if this function returned true. */
statusCheck?: (status: number) => MaybePromise<boolean>;

Expand All @@ -29,7 +29,7 @@ export type CachePredicateObject<R = unknown, D = unknown> = {

/** Check if the response matches this predicate. */
responseMatch?: (res: CacheAxiosResponse<R, D>) => MaybePromise<boolean>;
};
}

/**
* A simple function that receives a cache request config and should return a string id
Expand Down Expand Up @@ -68,14 +68,14 @@ export type CacheUpdaterFn<R, D> = (
* `delete` -> Deletes the request cache `predicate()` -> Determines if the cache can be
* reused, deleted or modified.
*/
export type CacheUpdaterRecord<R, D> = {
export interface CacheUpdaterRecord<R, D> {
[requestId: string]:
| 'delete'
| ((
cached: Exclude<StorageValue, LoadingStorageValue>,
response: CacheAxiosResponse<R, D>
) => MaybePromise<CachedStorageValue | 'delete' | 'ignore'>);
};
}

/**
* Updates any specified request cache by applying the response for this network call.
Expand Down

0 comments on commit 0199ad6

Please sign in to comment.