From d84548c93ec95d7364a5cc88c631930c192cecd8 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Sun, 26 Sep 2021 09:07:33 +0200 Subject: [PATCH 1/4] refine type names --- infinite/index.ts | 51 ++++++------------------ infinite/types.ts | 44 ++++++++++++++++++++- src/index.ts | 4 +- src/types.ts | 78 ++++++++++++++++--------------------- src/utils/cache.ts | 4 +- src/utils/config-context.ts | 4 +- src/utils/web-preset.ts | 4 +- 7 files changed, 94 insertions(+), 95 deletions(-) diff --git a/infinite/index.ts b/infinite/index.ts index 112077241..fd6e158c2 100644 --- a/infinite/index.ts +++ b/infinite/index.ts @@ -4,34 +4,37 @@ import { useRef, useState, useCallback } from 'react' import useSWR, { SWRConfig, - KeyLoader, Fetcher, SWRHook, MutatorCallback, Middleware, - ValueKey, - Result + Arguments } from 'swr' import { useIsomorphicLayoutEffect } from '../src/utils/env' import { serialize } from '../src/utils/serialize' import { isUndefined, isFunction, UNDEFINED } from '../src/utils/helper' import { withMiddleware } from '../src/utils/with-middleware' -import { SWRInfiniteConfiguration, SWRInfiniteResponse } from './types' +import { + SWRInfiniteConfiguration, + SWRInfiniteResponse, + SWRInfiniteHook, + InfiniteKeyLoader +} from './types' const INFINITE_PREFIX = '$inf$' -const getFirstPageKey = (getKey: KeyLoader) => { +const getFirstPageKey = (getKey: InfiniteKeyLoader) => { return serialize(getKey ? getKey(0, null) : null)[0] } -export const unstable_serialize = (getKey: KeyLoader) => { +export const unstable_serialize = (getKey: InfiniteKeyLoader) => { return INFINITE_PREFIX + getFirstPageKey(getKey) } -export const infinite = ((( +export const infinite = ((( useSWRNext: SWRHook ) => ( - getKey: KeyLoader, + getKey: InfiniteKeyLoader, fn: Fetcher | null, config: typeof SWRConfig.default & SWRInfiniteConfiguration ): SWRInfiniteResponse => { @@ -250,37 +253,5 @@ export const infinite = ((( } as SWRInfiniteResponse }) as unknown) as Middleware -export type InfiniteFetcher< - Args extends ValueKey = ValueKey, - Data = any -> = Args extends (readonly [...infer K]) - ? ((...args: [...K]) => Result) - : Args extends null - ? never - : Args extends (infer T) - ? (...args: [T]) => Result - : never - -interface SWRInfiniteHook { - ( - getKey: KeyLoader - ): SWRInfiniteResponse - ( - getKey: KeyLoader, - fn: InfiniteFetcher | null - ): SWRInfiniteResponse - ( - getKey: KeyLoader, - config: SWRInfiniteConfiguration | undefined - ): SWRInfiniteResponse - ( - ...args: [ - KeyLoader, - InfiniteFetcher | null, - SWRInfiniteConfiguration | undefined - ] - ): SWRInfiniteResponse -} - export default withMiddleware(useSWR, infinite) as SWRInfiniteHook export { SWRInfiniteConfiguration, SWRInfiniteResponse } diff --git a/infinite/types.ts b/infinite/types.ts index 93f65031b..ad1d4c3d4 100644 --- a/infinite/types.ts +++ b/infinite/types.ts @@ -1,9 +1,26 @@ -import { SWRConfiguration, Fetcher, SWRResponse, ValueKey } from 'swr' +import { SWRConfiguration, Fetcher, SWRResponse, Arguments } from 'swr' + +type FetcherReturnValue = Data | Promise + +export type InfiniteFetcher< + Args extends Arguments = Arguments, + Data = any +> = Args extends (readonly [...infer K]) + ? ((...args: [...K]) => FetcherReturnValue) + : Args extends null + ? never + : Args extends (infer T) + ? (...args: [T]) => FetcherReturnValue + : never + +export type InfiniteKeyLoader = + | ((index: number, previousPageData: any | null) => Args) + | null export type SWRInfiniteConfiguration< Data = any, Error = any, - Args extends ValueKey = ValueKey + Args extends Arguments = Arguments > = SWRConfiguration> & { initialSize?: number revalidateAll?: boolean @@ -17,3 +34,26 @@ export interface SWRInfiniteResponse size: number | ((_size: number) => number) ) => Promise } + +export interface SWRInfiniteHook { + ( + getKey: InfiniteKeyLoader + ): SWRInfiniteResponse + ( + getKey: InfiniteKeyLoader, + fetcher: InfiniteFetcher | null + ): SWRInfiniteResponse + ( + getKey: InfiniteKeyLoader, + config: + | SWRInfiniteConfiguration + | undefined + ): SWRInfiniteResponse + ( + getKey: InfiniteKeyLoader, + fetcher: InfiniteFetcher | null, + config: + | SWRInfiniteConfiguration + | undefined + ): SWRInfiniteResponse +} diff --git a/src/index.ts b/src/index.ts index c6a0b56d0..4e4deaa0b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,6 +21,6 @@ export { Fetcher, MutatorCallback, Middleware, - ValueKey, - Result + // + Arguments } from './types' diff --git a/src/types.ts b/src/types.ts index 5ebf1e913..b8b0ccea8 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,35 +1,33 @@ import * as revalidateEvents from './constants/revalidate-events' -export type Result = T | Promise +export type FetcherReturnValue = Data | Promise -export type Fetcher = +export type Fetcher = /** * () => [{ foo: string }, { bar: number }] | null - * * () => ( [{ foo: string }, { bar: number } ] as const | null ) */ - Args extends (() => readonly [...infer K] | null) - ? ((...args: [...K]) => Result) + SWRKey extends (() => readonly [...infer Args] | null) + ? ((...args: [...Args]) => FetcherReturnValue) : /** * [{ foo: string }, { bar: number } ] | null - * * [{ foo: string }, { bar: number } ] as const | null */ - Args extends (readonly [...infer K]) - ? ((...args: [...K]) => Result) + SWRKey extends (readonly [...infer Args]) + ? ((...args: [...Args]) => FetcherReturnValue) : /** * () => string | null * () => Record | null */ - Args extends (() => infer T | null) - ? (...args: [T]) => Result + SWRKey extends (() => infer Arg | null) + ? (...args: [Arg]) => FetcherReturnValue : /** * string | null | Record */ - Args extends null + SWRKey extends null ? never - : Args extends (infer T) - ? (...args: [T]) => Result + : SWRKey extends (infer Arg) + ? (...args: [Arg]) => FetcherReturnValue : never // Configuration types that are only used internally, not exposed to the user. @@ -94,55 +92,45 @@ export interface PublicConfiguration< export type FullConfiguration = InternalConfiguration & PublicConfiguration -export type ConfigOptions = { +export type ProviderConfiguration = { initFocus: (callback: () => void) => (() => void) | void initReconnect: (callback: () => void) => (() => void) | void } + export interface SWRHook { - (args: Args): SWRResponse< + (key: SWRKey): SWRResponse< Data, Error > - ( - args: Args, - fn: Fetcher | null - ): SWRResponse - ( - args: Args, - config: SWRConfiguration> | undefined + ( + key: SWRKey, + fetcher: Fetcher | null ): SWRResponse - ( - args: Args, - fn: Fetcher, - config: SWRConfiguration> + ( + key: SWRKey, + config: + | SWRConfiguration> + | undefined ): SWRResponse - ( - ...args: - | [Args] - | [Args, Fetcher | null] - | [ - Args, - SWRConfiguration> | undefined - ] - | [ - Args, - Fetcher | null, - SWRConfiguration> - ] + ( + key: SWRKey, + fetcher: Fetcher, + config: SWRConfiguration> ): SWRResponse } // Middlewares guarantee that a SWRHook receives a key, fetcher, and config as the argument -type SWRHookWithMiddleware = ( +export type Middleware = ( + useSWRNext: SWRHook +) => ( key: Args, fetcher: Fetcher | null, config: SWRConfiguration ) => SWRResponse -export type Middleware = (useSWRNext: SWRHook) => SWRHookWithMiddleware -export type TupleKey = [any, ...unknown[]] | readonly [any, ...unknown[]] -export type ValueKey = string | null | TupleKey | Record -export type Key = ValueKey | (() => ValueKey) +export type ArgumentsTuple = [any, ...unknown[]] | readonly [any, ...unknown[]] +export type Arguments = string | null | ArgumentsTuple | Record +export type Key = Arguments | (() => Arguments) export type MutatorCallback = ( currentValue?: Data @@ -206,7 +194,7 @@ export interface SWRResponse { isValidating: boolean } -export type KeyLoader = +export type KeyLoader = | ((index: number, previousPageData: any | null) => Args) | null diff --git a/src/utils/cache.ts b/src/utils/cache.ts index 9ab72660d..75ac78aa3 100644 --- a/src/utils/cache.ts +++ b/src/utils/cache.ts @@ -10,7 +10,7 @@ import { Cache, ScopedMutator, RevalidateCallback, - ConfigOptions + ProviderConfiguration } from '../types' const revalidateAllKeys = ( @@ -24,7 +24,7 @@ const revalidateAllKeys = ( export const initCache = ( provider: Cache, - options?: Partial + options?: Partial ): [Cache, ScopedMutator, () => void] | undefined => { // The global state for a specific provider will be used to deduplicate // requests and store listeners. As well as a mutate function that bound to diff --git a/src/utils/config-context.ts b/src/utils/config-context.ts index 508965c44..42bb5a843 100644 --- a/src/utils/config-context.ts +++ b/src/utils/config-context.ts @@ -7,7 +7,7 @@ import { useIsomorphicLayoutEffect } from './env' import { SWRConfiguration, FullConfiguration, - ConfigOptions, + ProviderConfiguration, Cache } from '../types' @@ -15,7 +15,7 @@ export const SWRConfigContext = createContext>({}) const SWRConfig: FC<{ value?: SWRConfiguration & - Partial & { + Partial & { provider?: (cache: Readonly) => Cache } }> = ({ children, value }) => { diff --git a/src/utils/web-preset.ts b/src/utils/web-preset.ts index 0e41f6a87..29d09b803 100644 --- a/src/utils/web-preset.ts +++ b/src/utils/web-preset.ts @@ -1,4 +1,4 @@ -import { ConfigOptions } from '../types' +import { ProviderConfiguration } from '../types' import { isUndefined, noop, hasWindow, hasDocument } from './helper' /** @@ -62,7 +62,7 @@ export const preset = { isVisible } as const -export const defaultConfigOptions: ConfigOptions = { +export const defaultConfigOptions: ProviderConfiguration = { initFocus, initReconnect } From 79be264a78e01f5556a4b0227c415e7fc16a1b0d Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Sun, 26 Sep 2021 09:11:23 +0200 Subject: [PATCH 2/4] refine type names cont. --- src/index.ts | 1 - src/types.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 4e4deaa0b..47b5e9831 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,6 +21,5 @@ export { Fetcher, MutatorCallback, Middleware, - // Arguments } from './types' diff --git a/src/types.ts b/src/types.ts index b8b0ccea8..95f2da361 100644 --- a/src/types.ts +++ b/src/types.ts @@ -128,7 +128,7 @@ export type Middleware = ( config: SWRConfiguration ) => SWRResponse -export type ArgumentsTuple = [any, ...unknown[]] | readonly [any, ...unknown[]] +type ArgumentsTuple = [any, ...unknown[]] | readonly [any, ...unknown[]] export type Arguments = string | null | ArgumentsTuple | Record export type Key = Arguments | (() => Arguments) From 35e60b95405f29ab0e44ccd0769a2c41904a34ca Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Sun, 26 Sep 2021 09:22:37 +0200 Subject: [PATCH 3/4] simplify SWRConfiguration type --- infinite/index.ts | 5 ++-- infinite/types.ts | 4 +-- src/types.ts | 63 ++++++++++++++++++++++++++--------------------- 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/infinite/index.ts b/infinite/index.ts index fd6e158c2..b6600576e 100644 --- a/infinite/index.ts +++ b/infinite/index.ts @@ -18,7 +18,8 @@ import { SWRInfiniteConfiguration, SWRInfiniteResponse, SWRInfiniteHook, - InfiniteKeyLoader + InfiniteKeyLoader, + InfiniteFetcher } from './types' const INFINITE_PREFIX = '$inf$' @@ -254,4 +255,4 @@ export const infinite = ((( }) as unknown) as Middleware export default withMiddleware(useSWR, infinite) as SWRInfiniteHook -export { SWRInfiniteConfiguration, SWRInfiniteResponse } +export { SWRInfiniteConfiguration, SWRInfiniteResponse, InfiniteFetcher } diff --git a/infinite/types.ts b/infinite/types.ts index ad1d4c3d4..d2a86a810 100644 --- a/infinite/types.ts +++ b/infinite/types.ts @@ -1,4 +1,4 @@ -import { SWRConfiguration, Fetcher, SWRResponse, Arguments } from 'swr' +import { SWRConfiguration, SWRResponse, Arguments } from 'swr' type FetcherReturnValue = Data | Promise @@ -21,7 +21,7 @@ export type SWRInfiniteConfiguration< Data = any, Error = any, Args extends Arguments = Arguments -> = SWRConfiguration> & { +> = SWRConfiguration & { initialSize?: number revalidateAll?: boolean persistSize?: boolean diff --git a/src/types.ts b/src/types.ts index 95f2da361..8ad32b05f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -9,22 +9,22 @@ export type Fetcher = */ SWRKey extends (() => readonly [...infer Args] | null) ? ((...args: [...Args]) => FetcherReturnValue) - : /** - * [{ foo: string }, { bar: number } ] | null - * [{ foo: string }, { bar: number } ] as const | null - */ - SWRKey extends (readonly [...infer Args]) + /** + * [{ foo: string }, { bar: number } ] | null + * [{ foo: string }, { bar: number } ] as const | null + */ + : SWRKey extends (readonly [...infer Args]) ? ((...args: [...Args]) => FetcherReturnValue) - : /** - * () => string | null - * () => Record | null - */ - SWRKey extends (() => infer Arg | null) + /** + * () => string | null + * () => Record | null + */ + : SWRKey extends (() => infer Arg | null) ? (...args: [Arg]) => FetcherReturnValue - : /** - * string | null | Record - */ - SWRKey extends null + /** + * string | null | Record + */ + : SWRKey extends null ? never : SWRKey extends (infer Arg) ? (...args: [Arg]) => FetcherReturnValue @@ -39,8 +39,7 @@ export interface InternalConfiguration { export interface PublicConfiguration< Data = any, Error = any, - Args extends Key = Key, - Fn = Fetcher + SWRKey extends Key = Key > { errorRetryInterval: number errorRetryCount?: number @@ -57,29 +56,29 @@ export interface PublicConfiguration< shouldRetryOnError: boolean suspense?: boolean fallbackData?: Data - fetcher?: Fn + fetcher?: Fetcher use?: Middleware[] fallback: { [key: string]: any } isPaused: () => boolean onLoadingSlow: ( key: string, - config: Readonly> + config: Readonly> ) => void onSuccess: ( data: Data, key: string, - config: Readonly> + config: Readonly> ) => void onError: ( err: Error, key: string, - config: Readonly> + config: Readonly> ) => void onErrorRetry: ( err: Error, key: string, - config: Readonly>, + config: Readonly>, revalidate: Revalidator, revalidateOpts: Required ) => void @@ -108,14 +107,23 @@ export interface SWRHook { ): SWRResponse ( key: SWRKey, - config: - | SWRConfiguration> - | undefined + config: SWRConfiguration | undefined ): SWRResponse ( key: SWRKey, fetcher: Fetcher, - config: SWRConfiguration> + config: SWRConfiguration + ): SWRResponse + ( + ...args: + | [SWRKey] + | [SWRKey, Fetcher | null] + | [SWRKey, SWRConfiguration | undefined] + | [ + SWRKey, + Fetcher | null, + SWRConfiguration + ] ): SWRResponse } @@ -183,9 +191,8 @@ export type KeyedMutator = ( export type SWRConfiguration< Data = any, Error = any, - Args extends Key = Key, - Fn = Fetcher -> = Partial> + SWRKey extends Key = Key +> = Partial> export interface SWRResponse { data?: Data From 1f0085abd2d5f57a5fc7c3d5452e77e4bca63a57 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Sun, 26 Sep 2021 17:30:55 +0200 Subject: [PATCH 4/4] apply review comments --- infinite/types.ts | 6 +++--- src/types.ts | 42 +++++++++++++++++++++--------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/infinite/types.ts b/infinite/types.ts index d2a86a810..e5f60bc9d 100644 --- a/infinite/types.ts +++ b/infinite/types.ts @@ -1,16 +1,16 @@ import { SWRConfiguration, SWRResponse, Arguments } from 'swr' -type FetcherReturnValue = Data | Promise +type FetcherResponse = Data | Promise export type InfiniteFetcher< Args extends Arguments = Arguments, Data = any > = Args extends (readonly [...infer K]) - ? ((...args: [...K]) => FetcherReturnValue) + ? ((...args: [...K]) => FetcherResponse) : Args extends null ? never : Args extends (infer T) - ? (...args: [T]) => FetcherReturnValue + ? (...args: [T]) => FetcherResponse : never export type InfiniteKeyLoader = diff --git a/src/types.ts b/src/types.ts index 8ad32b05f..3255d48eb 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,6 +1,6 @@ import * as revalidateEvents from './constants/revalidate-events' -export type FetcherReturnValue = Data | Promise +export type FetcherResponse = Data | Promise export type Fetcher = /** @@ -8,26 +8,26 @@ export type Fetcher = * () => ( [{ foo: string }, { bar: number } ] as const | null ) */ SWRKey extends (() => readonly [...infer Args] | null) - ? ((...args: [...Args]) => FetcherReturnValue) - /** - * [{ foo: string }, { bar: number } ] | null - * [{ foo: string }, { bar: number } ] as const | null - */ - : SWRKey extends (readonly [...infer Args]) - ? ((...args: [...Args]) => FetcherReturnValue) - /** - * () => string | null - * () => Record | null - */ - : SWRKey extends (() => infer Arg | null) - ? (...args: [Arg]) => FetcherReturnValue - /** - * string | null | Record - */ - : SWRKey extends null + ? ((...args: [...Args]) => FetcherResponse) + : /** + * [{ foo: string }, { bar: number } ] | null + * [{ foo: string }, { bar: number } ] as const | null + */ + SWRKey extends (readonly [...infer Args]) + ? ((...args: [...Args]) => FetcherResponse) + : /** + * () => string | null + * () => Record | null + */ + SWRKey extends (() => infer Arg | null) + ? (...args: [Arg]) => FetcherResponse + : /** + * string | null | Record + */ + SWRKey extends null ? never : SWRKey extends (infer Arg) - ? (...args: [Arg]) => FetcherReturnValue + ? (...args: [Arg]) => FetcherResponse : never // Configuration types that are only used internally, not exposed to the user. @@ -112,7 +112,7 @@ export interface SWRHook { ( key: SWRKey, fetcher: Fetcher, - config: SWRConfiguration + config: SWRConfiguration | undefined ): SWRResponse ( ...args: @@ -122,7 +122,7 @@ export interface SWRHook { | [ SWRKey, Fetcher | null, - SWRConfiguration + SWRConfiguration | undefined ] ): SWRResponse }